@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.
- package/dist/core/src/BaseSession.d.ts +1 -1
- package/dist/core/src/RPCMessages/VertoMessages.d.ts +7 -0
- package/dist/core/src/RPCMessages/VertoMessages.d.ts.map +1 -1
- package/dist/core/src/index.d.ts +2 -2
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/redux/features/component/componentSlice.d.ts +96 -0
- package/dist/core/src/redux/features/component/componentSlice.d.ts.map +1 -1
- package/dist/core/src/redux/rootReducer.d.ts +16 -0
- package/dist/core/src/redux/rootReducer.d.ts.map +1 -1
- package/dist/core/src/types/common.d.ts +16 -10
- package/dist/core/src/types/common.d.ts.map +1 -1
- package/dist/core/src/types/fabric.d.ts +0 -27
- package/dist/core/src/types/fabric.d.ts.map +1 -1
- package/dist/core/src/types/index.d.ts +67 -1
- package/dist/core/src/types/index.d.ts.map +1 -1
- package/dist/core/src/types/videoPlayback.d.ts +1 -7
- package/dist/core/src/types/videoPlayback.d.ts.map +1 -1
- package/dist/core/src/types/videoRecording.d.ts +1 -7
- package/dist/core/src/types/videoRecording.d.ts.map +1 -1
- package/dist/core/src/types/voice.d.ts +13 -2
- package/dist/core/src/types/voice.d.ts.map +1 -1
- package/dist/core/src/types/voiceCall.d.ts +96 -964
- package/dist/core/src/types/voiceCall.d.ts.map +1 -1
- package/dist/core/src/types/voiceCollect.d.ts +166 -0
- package/dist/core/src/types/voiceCollect.d.ts.map +1 -0
- package/dist/core/src/types/voiceConnect.d.ts +77 -0
- package/dist/core/src/types/voiceConnect.d.ts.map +1 -0
- package/dist/core/src/types/voiceDetect.d.ts +127 -0
- package/dist/core/src/types/voiceDetect.d.ts.map +1 -0
- package/dist/core/src/types/voicePlayback.d.ts +141 -0
- package/dist/core/src/types/voicePlayback.d.ts.map +1 -0
- package/dist/core/src/types/voicePrompt.d.ts +105 -0
- package/dist/core/src/types/voicePrompt.d.ts.map +1 -0
- package/dist/core/src/types/voiceRecording.d.ts +107 -0
- package/dist/core/src/types/voiceRecording.d.ts.map +1 -0
- package/dist/core/src/types/voiceSendDigits.d.ts +21 -0
- package/dist/core/src/types/voiceSendDigits.d.ts.map +1 -0
- package/dist/core/src/types/voiceTap.d.ts +116 -0
- package/dist/core/src/types/voiceTap.d.ts.map +1 -0
- package/dist/core/src/utils/constants.d.ts.map +1 -1
- package/dist/core/src/utils/eventUtils.d.ts +0 -2
- package/dist/core/src/utils/eventUtils.d.ts.map +1 -1
- package/dist/core/src/utils/interfaces.d.ts +19 -2
- package/dist/core/src/utils/interfaces.d.ts.map +1 -1
- package/dist/index.esm.js +636 -223
- package/dist/index.esm.js.map +4 -4
- package/dist/index.js +655 -233
- package/dist/index.js.map +4 -4
- package/dist/index.umd.js +26 -2
- package/dist/index.umd.js.map +1 -1
- package/dist/js/src/fabric/Conversation.d.ts +2 -2
- package/dist/js/src/fabric/Conversation.d.ts.map +1 -1
- package/dist/js/src/fabric/FabricRoomSession.d.ts +5 -4
- package/dist/js/src/fabric/FabricRoomSession.d.ts.map +1 -1
- package/dist/js/src/fabric/SignalWire.d.ts.map +1 -1
- package/dist/js/src/fabric/WSClient.d.ts +2 -2
- package/dist/js/src/fabric/WSClient.d.ts.map +1 -1
- package/dist/js/src/fabric/createWSClient.d.ts +1 -1
- package/dist/js/src/fabric/createWSClient.d.ts.map +1 -1
- package/dist/js/src/fabric/interfaces/capabilities.d.ts +28 -0
- package/dist/js/src/fabric/interfaces/capabilities.d.ts.map +1 -0
- package/dist/js/src/fabric/interfaces/conversation.d.ts +4 -4
- package/dist/js/src/fabric/interfaces/conversation.d.ts.map +1 -1
- package/dist/js/src/fabric/interfaces/index.d.ts +1 -0
- package/dist/js/src/fabric/interfaces/index.d.ts.map +1 -1
- package/dist/js/src/fabric/interfaces/wsClient.d.ts +2 -2
- package/dist/js/src/fabric/interfaces/wsClient.d.ts.map +1 -1
- package/dist/js/src/fabric/utils/capabilitiesHelpers.d.ts +28 -0
- package/dist/js/src/fabric/utils/capabilitiesHelpers.d.ts.map +1 -0
- package/dist/js/src/fabric/workers/callJoinWorker.d.ts.map +1 -1
- package/dist/js/src/fabric/workers/wsClientWorker.d.ts.map +1 -1
- package/dist/js/src/index.d.ts +2 -2
- package/dist/js/src/index.d.ts.map +1 -1
- package/dist/js/src/utils/interfaces/fabric.d.ts +6 -3
- package/dist/js/src/utils/interfaces/fabric.d.ts.map +1 -1
- package/dist/js/src/utils/paginatedResult.d.ts +4 -4
- package/dist/js/tsconfig.build.tsbuildinfo +1 -1
- package/dist/webrtc/src/BaseConnection.d.ts +78 -19
- package/dist/webrtc/src/BaseConnection.d.ts.map +1 -1
- package/dist/webrtc/src/RTCPeer.d.ts +11 -0
- package/dist/webrtc/src/RTCPeer.d.ts.map +1 -1
- package/dist/webrtc/src/utils/helpers.d.ts.map +1 -1
- package/dist/webrtc/src/utils/interfaces.d.ts +6 -0
- package/dist/webrtc/src/utils/interfaces.d.ts.map +1 -1
- package/dist/webrtc/src/utils/sdpHelpers.d.ts +27 -2
- package/dist/webrtc/src/utils/sdpHelpers.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/fabric/Conversation.ts +9 -7
- package/src/fabric/FabricRoomSession.ts +32 -32
- package/src/fabric/SignalWire.test.ts +2 -0
- package/src/fabric/SignalWire.ts +2 -0
- package/src/fabric/WSClient.ts +6 -10
- package/src/fabric/interfaces/capabilities.ts +30 -0
- package/src/fabric/interfaces/conversation.ts +5 -4
- package/src/fabric/interfaces/index.ts +2 -1
- package/src/fabric/interfaces/wsClient.ts +2 -2
- package/src/fabric/utils/capabilitiesHelpers.test.ts +201 -0
- package/src/fabric/utils/capabilitiesHelpers.ts +190 -0
- package/src/fabric/workers/callJoinWorker.ts +7 -6
- package/src/fabric/workers/wsClientWorker.ts +35 -12
- package/src/index.ts +1 -1
- package/src/utils/interfaces/fabric.ts +10 -3
- package/dist/core/src/utils/eventUtils.test.d.ts +0 -2
- 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
|
|
52
|
+
export type ConversationSubscribeCallback = (
|
|
53
53
|
event: ConversationEventParams
|
|
54
54
|
) => unknown
|
|
55
55
|
|
|
56
|
-
export interface
|
|
56
|
+
export interface ConversationSubscribeResult {
|
|
57
57
|
unsubscribe: () => void
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export interface ConversationChatMessagesSubscribeParams {
|
|
61
61
|
addressId: string
|
|
62
|
-
onMessage:
|
|
62
|
+
onMessage: ConversationSubscribeCallback
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
export type ConversationChatMessagesSubscribeResult =
|
|
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
|
-
|
|
77
|
+
// the server send the capabilities payload as an array of string
|
|
78
|
+
cfRoomSession.capabilities = mapCapabilityPayload(payload.capabilities)
|
|
78
79
|
|
|
79
|
-
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
//
|
|
40
|
-
|
|
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<
|
|
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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"eventUtils.test.d.ts","sourceRoot":"","sources":["../../../../../core/src/utils/eventUtils.test.ts"],"names":[],"mappings":""}
|