@signalwire/js 3.2.1 → 3.4.0-dev.202110121150.a4432f2.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.
- package/dist/core/src/BaseComponent.d.ts +20 -9
- package/dist/core/src/BaseComponent.d.ts.map +1 -1
- package/dist/core/src/BaseSession.d.ts +9 -2
- package/dist/core/src/BaseSession.d.ts.map +1 -1
- package/dist/core/src/RPCMessages/index.d.ts +1 -0
- package/dist/core/src/RPCMessages/index.d.ts.map +1 -1
- package/dist/core/src/index.d.ts +3 -3
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/redux/features/pubSub/pubSubSaga.d.ts.map +1 -1
- package/dist/core/src/redux/features/session/sessionSaga.d.ts.map +1 -1
- package/dist/core/src/redux/interfaces.d.ts +15 -6
- package/dist/core/src/redux/interfaces.d.ts.map +1 -1
- package/dist/core/src/redux/rootSaga.d.ts +4 -1
- package/dist/core/src/redux/rootSaga.d.ts.map +1 -1
- package/dist/core/src/rooms/RoomSessionPlayback.d.ts +20 -0
- package/dist/core/src/rooms/RoomSessionPlayback.d.ts.map +1 -0
- package/dist/core/src/rooms/RoomSessionPlayback.test.d.ts +2 -0
- package/dist/core/src/rooms/RoomSessionPlayback.test.d.ts.map +1 -0
- package/dist/core/src/rooms/RoomSessionRecording.d.ts +3 -0
- package/dist/core/src/rooms/RoomSessionRecording.d.ts.map +1 -1
- package/dist/core/src/rooms/index.d.ts +1 -0
- package/dist/core/src/rooms/index.d.ts.map +1 -1
- package/dist/core/src/rooms/methods.d.ts +11 -1
- package/dist/core/src/rooms/methods.d.ts.map +1 -1
- package/dist/core/src/types/index.d.ts +2 -2
- package/dist/core/src/types/index.d.ts.map +1 -1
- package/dist/core/src/types/utils.d.ts +60 -0
- package/dist/core/src/types/utils.d.ts.map +1 -1
- package/dist/core/src/types/video.d.ts +8 -5
- package/dist/core/src/types/video.d.ts.map +1 -1
- package/dist/core/src/types/videoMember.d.ts +60 -10
- package/dist/core/src/types/videoMember.d.ts.map +1 -1
- package/dist/core/src/types/videoPlayback.d.ts +110 -0
- package/dist/core/src/types/videoPlayback.d.ts.map +1 -0
- package/dist/core/src/types/videoRecording.d.ts +21 -5
- package/dist/core/src/types/videoRecording.d.ts.map +1 -1
- package/dist/core/src/types/videoRoomSession.d.ts +17 -1
- package/dist/core/src/types/videoRoomSession.d.ts.map +1 -1
- package/dist/core/src/utils/constants.d.ts +5 -0
- package/dist/core/src/utils/constants.d.ts.map +1 -1
- package/dist/core/src/utils/eventTransformUtils.d.ts +30 -0
- package/dist/core/src/utils/eventTransformUtils.d.ts.map +1 -0
- package/dist/core/src/utils/eventTransformUtils.test.d.ts +2 -0
- package/dist/core/src/utils/eventTransformUtils.test.d.ts.map +1 -0
- package/dist/core/src/utils/index.d.ts +8 -1
- package/dist/core/src/utils/index.d.ts.map +1 -1
- package/dist/core/src/utils/interfaces.d.ts +95 -4
- package/dist/core/src/utils/interfaces.d.ts.map +1 -1
- package/dist/core/src/utils/toExternalJSON.d.ts.map +1 -1
- package/dist/core/src/utils/toInternalEventName.d.ts.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +3 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +3 -3
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/dist/js/src/BaseRoomSession.d.ts +60 -0
- package/dist/js/src/BaseRoomSession.d.ts.map +1 -0
- package/dist/js/src/Client.d.ts +6 -5
- package/dist/js/src/Client.d.ts.map +1 -1
- package/dist/js/src/JWTSession.d.ts.map +1 -1
- package/dist/js/src/RoomSession.d.ts +27 -0
- package/dist/js/src/RoomSession.d.ts.map +1 -0
- package/dist/js/src/RoomSessionDevice.d.ts +16 -0
- package/dist/js/src/RoomSessionDevice.d.ts.map +1 -0
- package/dist/js/src/RoomSessionScreenShare.d.ts +16 -0
- package/dist/js/src/RoomSessionScreenShare.d.ts.map +1 -0
- package/dist/js/src/createClient.d.ts +1 -1
- package/dist/js/src/createClient.d.ts.map +1 -1
- package/dist/js/src/createRoomObject.d.ts +10 -2
- package/dist/js/src/createRoomObject.d.ts.map +1 -1
- package/dist/js/src/features/mediaElements/mediaElementsSagas.d.ts +4 -4
- package/dist/js/src/features/mediaElements/mediaElementsSagas.d.ts.map +1 -1
- package/dist/js/src/index.d.ts +1 -1
- package/dist/js/src/index.d.ts.map +1 -1
- package/dist/js/src/joinRoom.d.ts +2 -1
- package/dist/js/src/joinRoom.d.ts.map +1 -1
- package/dist/js/src/utils/interfaces.d.ts +32 -8
- package/dist/js/src/utils/interfaces.d.ts.map +1 -1
- package/dist/js/src/video.d.ts +5 -5
- package/dist/js/src/video.d.ts.map +1 -1
- package/dist/js/tsconfig.build.tsbuildinfo +1 -1
- package/dist/webrtc/src/BaseConnection.d.ts +1 -1
- package/dist/webrtc/src/BaseConnection.d.ts.map +1 -1
- package/dist/webrtc/src/RTCPeer.d.ts +8 -1
- package/dist/webrtc/src/RTCPeer.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/{Room.test.ts → BaseRoomSession.test.ts} +188 -5
- package/src/{Room.ts → BaseRoomSession.ts} +106 -60
- package/src/Client.ts +20 -12
- package/src/RoomSession.test.ts +28 -0
- package/src/RoomSession.ts +117 -0
- package/src/{RoomDevice.test.ts → RoomSessionDevice.test.ts} +7 -4
- package/src/{RoomDevice.ts → RoomSessionDevice.ts} +11 -8
- package/src/{RoomScreenShare.test.ts → RoomSessionScreenShare.test.ts} +7 -4
- package/src/{RoomScreenShare.ts → RoomSessionScreenShare.ts} +8 -5
- package/src/createClient.ts +7 -5
- package/src/createRoomObject.ts +36 -9
- package/src/features/mediaElements/mediaElementsSagas.ts +9 -18
- package/src/index.ts +5 -2
- package/src/joinRoom.ts +1 -0
- package/src/utils/interfaces.ts +38 -7
- package/src/video.ts +18 -5
- package/dist/js/src/Room.d.ts +0 -58
- package/dist/js/src/Room.d.ts.map +0 -1
- package/dist/js/src/RoomDevice.d.ts +0 -13
- package/dist/js/src/RoomDevice.d.ts.map +0 -1
- package/dist/js/src/RoomScreenShare.d.ts +0 -13
- package/dist/js/src/RoomScreenShare.d.ts.map +0 -1
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { EventEmitter, actions } from '@signalwire/core'
|
|
2
|
-
import {
|
|
2
|
+
import { createBaseRoomSessionObject } from './BaseRoomSession'
|
|
3
|
+
import type { RoomSession } from './RoomSession'
|
|
3
4
|
import { configureJestStore, configureFullStack } from './testUtils'
|
|
4
5
|
|
|
5
6
|
describe('Room Object', () => {
|
|
6
7
|
let store: any
|
|
7
|
-
let room:
|
|
8
|
+
let room: RoomSession
|
|
8
9
|
|
|
9
10
|
beforeEach(() => {
|
|
10
11
|
store = configureJestStore()
|
|
11
|
-
room =
|
|
12
|
+
room = createBaseRoomSessionObject<RoomSession>({
|
|
12
13
|
store,
|
|
13
14
|
emitter: new EventEmitter(),
|
|
14
15
|
})
|
|
16
|
+
// @ts-expect-error
|
|
15
17
|
room.execute = jest.fn()
|
|
16
18
|
// mock a room.subscribed event
|
|
19
|
+
// @ts-expect-error
|
|
17
20
|
room.onRoomSubscribed({
|
|
18
21
|
nodeId: 'node-id',
|
|
19
22
|
roomId: 'room-id',
|
|
@@ -29,6 +32,8 @@ describe('Room Object', () => {
|
|
|
29
32
|
expect(room.videoUnmute).toBeDefined()
|
|
30
33
|
expect(room.deaf).toBeDefined()
|
|
31
34
|
expect(room.undeaf).toBeDefined()
|
|
35
|
+
expect(room.setInputVolume).toBeDefined()
|
|
36
|
+
expect(room.setOutputVolume).toBeDefined()
|
|
32
37
|
expect(room.setMicrophoneVolume).toBeDefined()
|
|
33
38
|
expect(room.setSpeakerVolume).toBeDefined()
|
|
34
39
|
expect(room.setInputSensitivity).toBeDefined()
|
|
@@ -40,6 +45,8 @@ describe('Room Object', () => {
|
|
|
40
45
|
expect(room.showVideoMuted).toBeDefined()
|
|
41
46
|
expect(room.getRecordings).toBeDefined()
|
|
42
47
|
expect(room.startRecording).toBeDefined()
|
|
48
|
+
expect(room.getPlaybacks).toBeDefined()
|
|
49
|
+
expect(room.play).toBeDefined()
|
|
43
50
|
})
|
|
44
51
|
|
|
45
52
|
describe('getRecordings', () => {
|
|
@@ -53,12 +60,13 @@ describe('Room Object', () => {
|
|
|
53
60
|
recordings: recordingList,
|
|
54
61
|
})
|
|
55
62
|
|
|
56
|
-
room =
|
|
63
|
+
room = createBaseRoomSessionObject({
|
|
57
64
|
store,
|
|
58
65
|
// @ts-expect-error
|
|
59
66
|
emitter,
|
|
60
67
|
})
|
|
61
68
|
// mock a room.subscribed event
|
|
69
|
+
// @ts-expect-error
|
|
62
70
|
room.onRoomSubscribed({
|
|
63
71
|
nodeId: 'node-id',
|
|
64
72
|
roomId: '6e83849b-5cc2-4fc6-80ed-448113c8a426',
|
|
@@ -75,6 +83,7 @@ describe('Room Object', () => {
|
|
|
75
83
|
|
|
76
84
|
describe('startRecording', () => {
|
|
77
85
|
it('should return an interactive object', async () => {
|
|
86
|
+
// @ts-expect-error
|
|
78
87
|
;(room.execute as jest.Mock).mockResolvedValueOnce({
|
|
79
88
|
code: '200',
|
|
80
89
|
message: 'Recording started',
|
|
@@ -82,6 +91,7 @@ describe('Room Object', () => {
|
|
|
82
91
|
})
|
|
83
92
|
|
|
84
93
|
const recording = await room.startRecording()
|
|
94
|
+
// @ts-expect-error
|
|
85
95
|
recording.execute = jest.fn()
|
|
86
96
|
expect(recording.id).toEqual('c22d7223-5a01-49fe-8da0-46bec8e75e32')
|
|
87
97
|
expect(recording.roomSessionId).toEqual('room-session-id')
|
|
@@ -97,16 +107,19 @@ describe('Room Object', () => {
|
|
|
97
107
|
},
|
|
98
108
|
}
|
|
99
109
|
await recording.pause()
|
|
110
|
+
// @ts-expect-error
|
|
100
111
|
expect(recording.execute).toHaveBeenLastCalledWith({
|
|
101
112
|
...baseExecuteParams,
|
|
102
113
|
method: 'video.recording.pause',
|
|
103
114
|
})
|
|
104
115
|
await recording.resume()
|
|
116
|
+
// @ts-expect-error
|
|
105
117
|
expect(recording.execute).toHaveBeenLastCalledWith({
|
|
106
118
|
...baseExecuteParams,
|
|
107
119
|
method: 'video.recording.resume',
|
|
108
120
|
})
|
|
109
121
|
await recording.stop()
|
|
122
|
+
// @ts-expect-error
|
|
110
123
|
expect(recording.execute).toHaveBeenLastCalledWith({
|
|
111
124
|
...baseExecuteParams,
|
|
112
125
|
method: 'video.recording.stop',
|
|
@@ -114,11 +127,13 @@ describe('Room Object', () => {
|
|
|
114
127
|
})
|
|
115
128
|
|
|
116
129
|
it('should work with simulataneous recordings', async () => {
|
|
130
|
+
// @ts-expect-error
|
|
117
131
|
;(room.execute as jest.Mock).mockResolvedValueOnce({
|
|
118
132
|
code: '200',
|
|
119
133
|
message: 'Recording started',
|
|
120
134
|
recording_id: 'first-recording',
|
|
121
135
|
})
|
|
136
|
+
// @ts-expect-error
|
|
122
137
|
;(room.execute as jest.Mock).mockResolvedValueOnce({
|
|
123
138
|
code: '200',
|
|
124
139
|
message: 'Recording started',
|
|
@@ -126,13 +141,16 @@ describe('Room Object', () => {
|
|
|
126
141
|
})
|
|
127
142
|
|
|
128
143
|
const firstRecording = await room.startRecording()
|
|
144
|
+
// @ts-expect-error
|
|
129
145
|
firstRecording.execute = jest.fn()
|
|
130
146
|
const secondRecording = await room.startRecording()
|
|
147
|
+
// @ts-expect-error
|
|
131
148
|
secondRecording.execute = jest.fn()
|
|
132
149
|
|
|
133
150
|
expect(firstRecording.id).toEqual('first-recording')
|
|
134
151
|
expect(firstRecording.roomSessionId).toEqual('room-session-id')
|
|
135
152
|
await firstRecording.stop()
|
|
153
|
+
// @ts-expect-error
|
|
136
154
|
expect(firstRecording.execute).toHaveBeenLastCalledWith({
|
|
137
155
|
method: 'video.recording.stop',
|
|
138
156
|
params: {
|
|
@@ -144,6 +162,7 @@ describe('Room Object', () => {
|
|
|
144
162
|
expect(secondRecording.id).toEqual('second-recording')
|
|
145
163
|
expect(secondRecording.roomSessionId).toEqual('room-session-id')
|
|
146
164
|
await secondRecording.stop()
|
|
165
|
+
// @ts-expect-error
|
|
147
166
|
expect(secondRecording.execute).toHaveBeenLastCalledWith({
|
|
148
167
|
method: 'video.recording.stop',
|
|
149
168
|
params: {
|
|
@@ -154,16 +173,180 @@ describe('Room Object', () => {
|
|
|
154
173
|
})
|
|
155
174
|
})
|
|
156
175
|
|
|
176
|
+
describe('playback methods', () => {
|
|
177
|
+
it('getPlaybacks should return an array of playbacks', async () => {
|
|
178
|
+
const { store, session, emitter } = configureFullStack()
|
|
179
|
+
const playbacks = [{ id: 'playbackOne' }, { id: 'playbackTwo' }]
|
|
180
|
+
|
|
181
|
+
session.execute = jest.fn().mockResolvedValue({
|
|
182
|
+
code: '200',
|
|
183
|
+
message: 'OK',
|
|
184
|
+
playbacks,
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
room = createBaseRoomSessionObject({
|
|
188
|
+
store,
|
|
189
|
+
// @ts-expect-error
|
|
190
|
+
emitter,
|
|
191
|
+
})
|
|
192
|
+
// mock a room.subscribed event
|
|
193
|
+
// @ts-expect-error
|
|
194
|
+
room.onRoomSubscribed({
|
|
195
|
+
nodeId: 'node-id',
|
|
196
|
+
roomId: '6e83849b-5cc2-4fc6-80ed-448113c8a426',
|
|
197
|
+
roomSessionId: '8e03ac25-8622-411a-95fc-f897b34ac9e7',
|
|
198
|
+
memberId: 'member-id',
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
const result = await room.getPlaybacks()
|
|
202
|
+
expect(result).toStrictEqual({
|
|
203
|
+
playbacks,
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
it('play should return an interactive object', async () => {
|
|
208
|
+
// @ts-expect-error
|
|
209
|
+
;(room.execute as jest.Mock).mockResolvedValueOnce({
|
|
210
|
+
code: '200',
|
|
211
|
+
message: 'Playback started',
|
|
212
|
+
playback: {
|
|
213
|
+
id: 'c22d7223-5a01-49fe-8da0-46bec8e75e32',
|
|
214
|
+
state: 'playing',
|
|
215
|
+
started_at: 1234,
|
|
216
|
+
},
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
const playback = await room.play({
|
|
220
|
+
url: 'rtmp://jest.example.com/bla',
|
|
221
|
+
volume: 5,
|
|
222
|
+
})
|
|
223
|
+
// @ts-expect-error
|
|
224
|
+
playback.execute = jest.fn()
|
|
225
|
+
|
|
226
|
+
// @ts-expect-error
|
|
227
|
+
expect(room.execute).toHaveBeenLastCalledWith({
|
|
228
|
+
method: 'video.playback.start',
|
|
229
|
+
params: {
|
|
230
|
+
room_session_id: 'room-session-id',
|
|
231
|
+
url: 'rtmp://jest.example.com/bla',
|
|
232
|
+
volume: 5,
|
|
233
|
+
},
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
expect(playback.id).toEqual('c22d7223-5a01-49fe-8da0-46bec8e75e32')
|
|
237
|
+
expect(playback.roomSessionId).toEqual('room-session-id')
|
|
238
|
+
expect(playback.pause).toBeDefined()
|
|
239
|
+
expect(playback.resume).toBeDefined()
|
|
240
|
+
expect(playback.stop).toBeDefined()
|
|
241
|
+
|
|
242
|
+
const baseExecuteParams = {
|
|
243
|
+
method: '',
|
|
244
|
+
params: {
|
|
245
|
+
room_session_id: 'room-session-id',
|
|
246
|
+
playback_id: 'c22d7223-5a01-49fe-8da0-46bec8e75e32',
|
|
247
|
+
},
|
|
248
|
+
}
|
|
249
|
+
await playback.pause()
|
|
250
|
+
// @ts-expect-error
|
|
251
|
+
expect(playback.execute).toHaveBeenLastCalledWith({
|
|
252
|
+
...baseExecuteParams,
|
|
253
|
+
method: 'video.playback.pause',
|
|
254
|
+
})
|
|
255
|
+
await playback.resume()
|
|
256
|
+
// @ts-expect-error
|
|
257
|
+
expect(playback.execute).toHaveBeenLastCalledWith({
|
|
258
|
+
...baseExecuteParams,
|
|
259
|
+
method: 'video.playback.resume',
|
|
260
|
+
})
|
|
261
|
+
await playback.stop()
|
|
262
|
+
// @ts-expect-error
|
|
263
|
+
expect(playback.execute).toHaveBeenLastCalledWith({
|
|
264
|
+
...baseExecuteParams,
|
|
265
|
+
method: 'video.playback.stop',
|
|
266
|
+
})
|
|
267
|
+
await playback.setVolume(30)
|
|
268
|
+
// @ts-expect-error
|
|
269
|
+
expect(playback.execute).toHaveBeenLastCalledWith({
|
|
270
|
+
method: 'video.playback.set_volume',
|
|
271
|
+
params: {
|
|
272
|
+
room_session_id: 'room-session-id',
|
|
273
|
+
playback_id: 'c22d7223-5a01-49fe-8da0-46bec8e75e32',
|
|
274
|
+
volume: 30,
|
|
275
|
+
},
|
|
276
|
+
})
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
it('play should work with simulataneous playbacks', async () => {
|
|
280
|
+
// @ts-expect-error
|
|
281
|
+
;(room.execute as jest.Mock).mockResolvedValueOnce({
|
|
282
|
+
code: '200',
|
|
283
|
+
message: 'Playback started',
|
|
284
|
+
playback: {
|
|
285
|
+
id: 'first-playback',
|
|
286
|
+
state: 'playing',
|
|
287
|
+
started_at: 1234,
|
|
288
|
+
},
|
|
289
|
+
})
|
|
290
|
+
// @ts-expect-error
|
|
291
|
+
;(room.execute as jest.Mock).mockResolvedValueOnce({
|
|
292
|
+
code: '200',
|
|
293
|
+
message: 'Playback started',
|
|
294
|
+
playback: {
|
|
295
|
+
id: 'second-playback',
|
|
296
|
+
state: 'playing',
|
|
297
|
+
started_at: 1234,
|
|
298
|
+
},
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
const firstPlayback = await room.play({
|
|
302
|
+
url: 'url-one',
|
|
303
|
+
})
|
|
304
|
+
// @ts-expect-error
|
|
305
|
+
firstPlayback.execute = jest.fn()
|
|
306
|
+
const secondPlayback = await room.play({
|
|
307
|
+
url: 'url-two',
|
|
308
|
+
})
|
|
309
|
+
// @ts-expect-error
|
|
310
|
+
secondPlayback.execute = jest.fn()
|
|
311
|
+
|
|
312
|
+
expect(firstPlayback.id).toEqual('first-playback')
|
|
313
|
+
expect(firstPlayback.roomSessionId).toEqual('room-session-id')
|
|
314
|
+
await firstPlayback.stop()
|
|
315
|
+
// @ts-expect-error
|
|
316
|
+
expect(firstPlayback.execute).toHaveBeenLastCalledWith({
|
|
317
|
+
method: 'video.playback.stop',
|
|
318
|
+
params: {
|
|
319
|
+
room_session_id: 'room-session-id',
|
|
320
|
+
playback_id: 'first-playback',
|
|
321
|
+
},
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
expect(secondPlayback.id).toEqual('second-playback')
|
|
325
|
+
expect(secondPlayback.roomSessionId).toEqual('room-session-id')
|
|
326
|
+
await secondPlayback.stop()
|
|
327
|
+
// @ts-expect-error
|
|
328
|
+
expect(secondPlayback.execute).toHaveBeenLastCalledWith({
|
|
329
|
+
method: 'video.playback.stop',
|
|
330
|
+
params: {
|
|
331
|
+
room_session_id: 'room-session-id',
|
|
332
|
+
playback_id: 'second-playback',
|
|
333
|
+
},
|
|
334
|
+
})
|
|
335
|
+
})
|
|
336
|
+
})
|
|
337
|
+
|
|
157
338
|
describe('as event emitter', () => {
|
|
158
339
|
it('should listen on the talking events', () => {
|
|
159
340
|
const { store, session, emitter } = configureFullStack()
|
|
160
|
-
room =
|
|
341
|
+
room = createBaseRoomSessionObject({
|
|
161
342
|
store,
|
|
162
343
|
// @ts-expect-error
|
|
163
344
|
emitter,
|
|
164
345
|
})
|
|
346
|
+
// @ts-expect-error
|
|
165
347
|
room.execute = jest.fn()
|
|
166
348
|
// mock a room.subscribed event
|
|
349
|
+
// @ts-expect-error
|
|
167
350
|
room.onRoomSubscribed({
|
|
168
351
|
nodeId: 'node-id',
|
|
169
352
|
roomId: '6e83849b-5cc2-4fc6-80ed-448113c8a426',
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
extendComponent,
|
|
7
7
|
BaseComponentOptions,
|
|
8
8
|
BaseConnectionContract,
|
|
9
|
+
toLocalEvent,
|
|
10
|
+
toExternalJSON,
|
|
9
11
|
} from '@signalwire/core'
|
|
10
12
|
import {
|
|
11
13
|
getDisplayMedia,
|
|
@@ -13,14 +15,15 @@ import {
|
|
|
13
15
|
BaseConnectionOptions,
|
|
14
16
|
BaseConnectionStateEventTypes,
|
|
15
17
|
} from '@signalwire/webrtc'
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
+
import type {
|
|
19
|
+
RoomSessionObjectEvents,
|
|
18
20
|
CreateScreenShareObjectOptions,
|
|
19
21
|
AddDeviceOptions,
|
|
20
22
|
AddCameraOptions,
|
|
21
23
|
AddMicrophoneOptions,
|
|
22
24
|
BaseRoomInterface,
|
|
23
25
|
RoomMethods,
|
|
26
|
+
StartScreenShareOptions,
|
|
24
27
|
} from './utils/interfaces'
|
|
25
28
|
import {
|
|
26
29
|
ROOM_COMPONENT_LISTENERS,
|
|
@@ -28,25 +31,29 @@ import {
|
|
|
28
31
|
} from './utils/constants'
|
|
29
32
|
import { audioSetSpeakerAction } from './features/actions'
|
|
30
33
|
import {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
} from './
|
|
35
|
-
import {
|
|
34
|
+
RoomSessionScreenShareAPI,
|
|
35
|
+
RoomSessionScreenShareConnection,
|
|
36
|
+
RoomSessionScreenShare,
|
|
37
|
+
} from './RoomSessionScreenShare'
|
|
38
|
+
import {
|
|
39
|
+
RoomSessionDeviceAPI,
|
|
40
|
+
RoomSessionDeviceConnection,
|
|
41
|
+
RoomSessionDevice,
|
|
42
|
+
} from './RoomSessionDevice'
|
|
36
43
|
|
|
37
|
-
export interface
|
|
44
|
+
export interface BaseRoomSession<T>
|
|
38
45
|
extends RoomMethods,
|
|
39
|
-
BaseConnectionContract<
|
|
40
|
-
join(): Promise<
|
|
46
|
+
BaseConnectionContract<RoomSessionObjectEvents> {
|
|
47
|
+
join(): Promise<T>
|
|
41
48
|
leave(): Promise<void>
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
export class
|
|
45
|
-
extends BaseConnection<
|
|
51
|
+
export class RoomSessionConnection
|
|
52
|
+
extends BaseConnection<RoomSessionObjectEvents>
|
|
46
53
|
implements BaseRoomInterface
|
|
47
54
|
{
|
|
48
|
-
private _screenShareList = new Set<
|
|
49
|
-
private _deviceList = new Set<
|
|
55
|
+
private _screenShareList = new Set<RoomSessionScreenShare>()
|
|
56
|
+
private _deviceList = new Set<RoomSessionDevice>()
|
|
50
57
|
|
|
51
58
|
get screenShareList() {
|
|
52
59
|
return Array.from(this._screenShareList)
|
|
@@ -61,12 +68,13 @@ export class RoomConnection
|
|
|
61
68
|
return new Map<string | string[], EventTransform>([
|
|
62
69
|
[
|
|
63
70
|
[
|
|
64
|
-
'video.
|
|
71
|
+
toLocalEvent('video.recording.start'),
|
|
65
72
|
'video.recording.started',
|
|
66
73
|
'video.recording.updated',
|
|
67
74
|
'video.recording.ended',
|
|
68
75
|
],
|
|
69
76
|
{
|
|
77
|
+
type: 'roomSessionRecording',
|
|
70
78
|
instanceFactory: (_payload: any) => {
|
|
71
79
|
return Rooms.createRoomSessionRecordingObject({
|
|
72
80
|
store: this.store,
|
|
@@ -76,31 +84,61 @@ export class RoomConnection
|
|
|
76
84
|
},
|
|
77
85
|
payloadTransform: (payload: any) => {
|
|
78
86
|
if (payload?.recording) {
|
|
79
|
-
return {
|
|
80
|
-
...payload
|
|
81
|
-
|
|
82
|
-
}
|
|
87
|
+
return toExternalJSON({
|
|
88
|
+
...payload.recording,
|
|
89
|
+
room_session_id: this.roomSessionId,
|
|
90
|
+
})
|
|
83
91
|
}
|
|
84
|
-
|
|
92
|
+
|
|
93
|
+
return toExternalJSON({
|
|
85
94
|
id: payload.recording_id,
|
|
86
|
-
|
|
87
|
-
}
|
|
95
|
+
room_session_id: this.roomSessionId,
|
|
96
|
+
})
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
[
|
|
101
|
+
[
|
|
102
|
+
toLocalEvent('video.playback.start'),
|
|
103
|
+
'video.playback.started',
|
|
104
|
+
'video.playback.updated',
|
|
105
|
+
'video.playback.ended',
|
|
106
|
+
],
|
|
107
|
+
{
|
|
108
|
+
type: 'roomSessionPlayback',
|
|
109
|
+
instanceFactory: (_payload: any) => {
|
|
110
|
+
return Rooms.createRoomSessionPlaybackObject({
|
|
111
|
+
store: this.store,
|
|
112
|
+
// @ts-expect-error
|
|
113
|
+
emitter: this.emitter,
|
|
114
|
+
})
|
|
115
|
+
},
|
|
116
|
+
payloadTransform: (payload: any) => {
|
|
117
|
+
return toExternalJSON({
|
|
118
|
+
...payload.playback,
|
|
119
|
+
room_session_id: this.roomSessionId,
|
|
120
|
+
})
|
|
88
121
|
},
|
|
89
122
|
},
|
|
90
123
|
],
|
|
91
124
|
])
|
|
92
125
|
}
|
|
93
126
|
|
|
127
|
+
/** @deprecated Use {@link startScreenShare} instead. */
|
|
128
|
+
async createScreenShareObject(opts: CreateScreenShareObjectOptions = {}) {
|
|
129
|
+
return this.startScreenShare(opts)
|
|
130
|
+
}
|
|
131
|
+
|
|
94
132
|
/**
|
|
95
133
|
* Allow sharing the screen within the room.
|
|
96
134
|
*/
|
|
97
|
-
async
|
|
135
|
+
async startScreenShare(opts: StartScreenShareOptions = {}) {
|
|
98
136
|
const { autoJoin = true, audio = false, video = true } = opts
|
|
99
137
|
const displayStream: MediaStream = await getDisplayMedia({
|
|
100
138
|
audio: audio === true ? SCREENSHARE_AUDIO_CONSTRAINTS : audio,
|
|
101
139
|
video,
|
|
102
140
|
})
|
|
103
|
-
const options: BaseConnectionOptions<
|
|
141
|
+
const options: BaseConnectionOptions<RoomSessionObjectEvents> = {
|
|
104
142
|
...this.options,
|
|
105
143
|
screenShare: true,
|
|
106
144
|
recoverCall: false,
|
|
@@ -115,11 +153,11 @@ export class RoomConnection
|
|
|
115
153
|
|
|
116
154
|
const screenShare = connect<
|
|
117
155
|
BaseConnectionStateEventTypes,
|
|
118
|
-
|
|
119
|
-
|
|
156
|
+
RoomSessionScreenShareConnection,
|
|
157
|
+
RoomSessionScreenShare
|
|
120
158
|
>({
|
|
121
159
|
store: this.store,
|
|
122
|
-
Component:
|
|
160
|
+
Component: RoomSessionScreenShareAPI,
|
|
123
161
|
componentListeners: ROOM_COMPONENT_LISTENERS,
|
|
124
162
|
})(options)
|
|
125
163
|
|
|
@@ -184,7 +222,7 @@ export class RoomConnection
|
|
|
184
222
|
)
|
|
185
223
|
}
|
|
186
224
|
|
|
187
|
-
const options: BaseConnectionOptions<
|
|
225
|
+
const options: BaseConnectionOptions<RoomSessionObjectEvents> = {
|
|
188
226
|
...this.options,
|
|
189
227
|
localStream: undefined,
|
|
190
228
|
remoteStream: undefined,
|
|
@@ -201,11 +239,11 @@ export class RoomConnection
|
|
|
201
239
|
|
|
202
240
|
const roomDevice = connect<
|
|
203
241
|
BaseConnectionStateEventTypes,
|
|
204
|
-
|
|
205
|
-
|
|
242
|
+
RoomSessionDeviceConnection,
|
|
243
|
+
RoomSessionDevice
|
|
206
244
|
>({
|
|
207
245
|
store: this.store,
|
|
208
|
-
Component:
|
|
246
|
+
Component: RoomSessionDeviceAPI,
|
|
209
247
|
componentListeners: ROOM_COMPONENT_LISTENERS,
|
|
210
248
|
})(options)
|
|
211
249
|
|
|
@@ -226,7 +264,7 @@ export class RoomConnection
|
|
|
226
264
|
}
|
|
227
265
|
|
|
228
266
|
join() {
|
|
229
|
-
return super.invite<
|
|
267
|
+
return super.invite<BaseRoomSession<this>>()
|
|
230
268
|
}
|
|
231
269
|
|
|
232
270
|
leave() {
|
|
@@ -276,40 +314,48 @@ export class RoomConnection
|
|
|
276
314
|
}
|
|
277
315
|
}
|
|
278
316
|
|
|
279
|
-
export const
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
317
|
+
export const RoomSessionAPI = extendComponent<
|
|
318
|
+
RoomSessionConnection,
|
|
319
|
+
RoomMethods
|
|
320
|
+
>(RoomSessionConnection, {
|
|
321
|
+
audioMute: Rooms.audioMuteMember,
|
|
322
|
+
audioUnmute: Rooms.audioUnmuteMember,
|
|
323
|
+
videoMute: Rooms.videoMuteMember,
|
|
324
|
+
videoUnmute: Rooms.videoUnmuteMember,
|
|
325
|
+
deaf: Rooms.deafMember,
|
|
326
|
+
undeaf: Rooms.undeafMember,
|
|
327
|
+
setInputVolume: Rooms.setInputVolumeMember,
|
|
328
|
+
setOutputVolume: Rooms.setOutputVolumeMember,
|
|
329
|
+
setMicrophoneVolume: Rooms.setInputVolumeMember,
|
|
330
|
+
setSpeakerVolume: Rooms.setOutputVolumeMember,
|
|
331
|
+
setInputSensitivity: Rooms.setInputSensitivityMember,
|
|
332
|
+
removeMember: Rooms.removeMember,
|
|
333
|
+
getMembers: Rooms.getMembers,
|
|
334
|
+
getLayouts: Rooms.getLayouts,
|
|
335
|
+
setLayout: Rooms.setLayout,
|
|
336
|
+
hideVideoMuted: Rooms.hideVideoMuted,
|
|
337
|
+
showVideoMuted: Rooms.showVideoMuted,
|
|
338
|
+
getRecordings: Rooms.getRecordings,
|
|
339
|
+
startRecording: Rooms.startRecording,
|
|
340
|
+
getPlaybacks: Rooms.getPlaybacks,
|
|
341
|
+
play: Rooms.play,
|
|
342
|
+
})
|
|
301
343
|
|
|
302
|
-
type
|
|
344
|
+
type RoomSessionObjectEventsHandlerMapping = RoomSessionObjectEvents &
|
|
303
345
|
BaseConnectionStateEventTypes
|
|
304
346
|
|
|
305
347
|
/** @internal */
|
|
306
|
-
export const
|
|
307
|
-
params: BaseComponentOptions<
|
|
308
|
-
):
|
|
309
|
-
const room = connect<
|
|
348
|
+
export const createBaseRoomSessionObject = <RoomSessionType>(
|
|
349
|
+
params: BaseComponentOptions<RoomSessionObjectEventsHandlerMapping>
|
|
350
|
+
): BaseRoomSession<RoomSessionType> => {
|
|
351
|
+
const room = connect<
|
|
352
|
+
RoomSessionObjectEventsHandlerMapping,
|
|
353
|
+
RoomSessionConnection,
|
|
354
|
+
BaseRoomSession<RoomSessionType>
|
|
355
|
+
>({
|
|
310
356
|
store: params.store,
|
|
311
357
|
customSagas: params.customSagas,
|
|
312
|
-
Component:
|
|
358
|
+
Component: RoomSessionAPI,
|
|
313
359
|
componentListeners: ROOM_COMPONENT_LISTENERS,
|
|
314
360
|
})(params)
|
|
315
361
|
|
package/src/Client.ts
CHANGED
|
@@ -7,48 +7,56 @@ import {
|
|
|
7
7
|
import type { CustomSaga } from '@signalwire/core'
|
|
8
8
|
import { ConnectionOptions } from '@signalwire/webrtc'
|
|
9
9
|
import { makeMediaElementsSaga } from './features/mediaElements/mediaElementsSagas'
|
|
10
|
-
import {
|
|
10
|
+
import { RoomSession } from './RoomSession'
|
|
11
|
+
import {
|
|
12
|
+
createBaseRoomSessionObject,
|
|
13
|
+
RoomSessionConnection,
|
|
14
|
+
} from './BaseRoomSession'
|
|
11
15
|
|
|
12
|
-
export interface Client
|
|
13
|
-
|
|
16
|
+
export interface Client<RoomSessionType = RoomSession>
|
|
17
|
+
extends ClientContract<Client<RoomSessionType>, ClientEvents> {
|
|
18
|
+
rooms: ClientAPI<RoomSessionType>['rooms']
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
export interface MakeRoomOptions extends ConnectionOptions {
|
|
17
|
-
|
|
22
|
+
rootElement?: HTMLElement
|
|
18
23
|
applyLocalVideoOverlay?: boolean
|
|
19
24
|
stopCameraWhileMuted?: boolean
|
|
20
25
|
stopMicrophoneWhileMuted?: boolean
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
export class ClientAPI
|
|
28
|
+
export class ClientAPI<
|
|
29
|
+
RoomSessionType = RoomSession
|
|
30
|
+
> extends BaseClient<ClientEvents> {
|
|
24
31
|
get rooms() {
|
|
25
32
|
return {
|
|
26
33
|
makeRoomObject: (makeRoomOptions: MakeRoomOptions) => {
|
|
27
34
|
const {
|
|
28
|
-
|
|
35
|
+
rootElement,
|
|
29
36
|
applyLocalVideoOverlay = true,
|
|
30
37
|
stopCameraWhileMuted = true,
|
|
31
38
|
stopMicrophoneWhileMuted = true,
|
|
32
39
|
...options
|
|
33
40
|
} = makeRoomOptions
|
|
34
41
|
|
|
35
|
-
const customSagas: Array<CustomSaga<
|
|
42
|
+
const customSagas: Array<CustomSaga<RoomSessionConnection>> = []
|
|
36
43
|
|
|
37
44
|
/**
|
|
38
|
-
* If the user provides a `
|
|
39
|
-
* handle the Audio and Video elements
|
|
45
|
+
* If the user provides a `roomElement` we'll
|
|
46
|
+
* automatically handle the Audio and Video elements
|
|
47
|
+
* for them
|
|
40
48
|
*/
|
|
41
|
-
if (
|
|
49
|
+
if (rootElement) {
|
|
42
50
|
customSagas.push(
|
|
43
51
|
makeMediaElementsSaga({
|
|
44
|
-
|
|
52
|
+
rootElement,
|
|
45
53
|
applyLocalVideoOverlay,
|
|
46
54
|
speakerId: options.speakerId,
|
|
47
55
|
})
|
|
48
56
|
)
|
|
49
57
|
}
|
|
50
58
|
|
|
51
|
-
const room =
|
|
59
|
+
const room = createBaseRoomSessionObject<RoomSessionType>({
|
|
52
60
|
...options,
|
|
53
61
|
store: this.store,
|
|
54
62
|
// @ts-expect-error
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { RoomSession, UNSAFE_PROP_ACCESS } from './RoomSession'
|
|
2
|
+
|
|
3
|
+
describe('RoomSession Object', () => {
|
|
4
|
+
it('should control which properties the user can access before connecting the room.', async () => {
|
|
5
|
+
const roomSession = new RoomSession({
|
|
6
|
+
token: '<some-token>',
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
expect(() => roomSession.active).not.toThrow()
|
|
10
|
+
expect(() => roomSession.memberId).not.toThrow()
|
|
11
|
+
expect(() => roomSession.join()).not.toThrow()
|
|
12
|
+
UNSAFE_PROP_ACCESS.map((prop) => {
|
|
13
|
+
// @ts-expect-error
|
|
14
|
+
expect(() => roomSession[prop]).toThrow()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
// @ts-expect-error
|
|
18
|
+
roomSession.state = 'active'
|
|
19
|
+
|
|
20
|
+
expect(() => roomSession.active).not.toThrow()
|
|
21
|
+
expect(() => roomSession.memberId).not.toThrow()
|
|
22
|
+
expect(() => roomSession.join()).not.toThrow()
|
|
23
|
+
UNSAFE_PROP_ACCESS.map((prop) => {
|
|
24
|
+
// @ts-expect-error
|
|
25
|
+
expect(() => roomSession[prop]).not.toThrow()
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
})
|