@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.
Files changed (109) hide show
  1. package/dist/core/src/BaseComponent.d.ts +20 -9
  2. package/dist/core/src/BaseComponent.d.ts.map +1 -1
  3. package/dist/core/src/BaseSession.d.ts +9 -2
  4. package/dist/core/src/BaseSession.d.ts.map +1 -1
  5. package/dist/core/src/RPCMessages/index.d.ts +1 -0
  6. package/dist/core/src/RPCMessages/index.d.ts.map +1 -1
  7. package/dist/core/src/index.d.ts +3 -3
  8. package/dist/core/src/index.d.ts.map +1 -1
  9. package/dist/core/src/redux/features/pubSub/pubSubSaga.d.ts.map +1 -1
  10. package/dist/core/src/redux/features/session/sessionSaga.d.ts.map +1 -1
  11. package/dist/core/src/redux/interfaces.d.ts +15 -6
  12. package/dist/core/src/redux/interfaces.d.ts.map +1 -1
  13. package/dist/core/src/redux/rootSaga.d.ts +4 -1
  14. package/dist/core/src/redux/rootSaga.d.ts.map +1 -1
  15. package/dist/core/src/rooms/RoomSessionPlayback.d.ts +20 -0
  16. package/dist/core/src/rooms/RoomSessionPlayback.d.ts.map +1 -0
  17. package/dist/core/src/rooms/RoomSessionPlayback.test.d.ts +2 -0
  18. package/dist/core/src/rooms/RoomSessionPlayback.test.d.ts.map +1 -0
  19. package/dist/core/src/rooms/RoomSessionRecording.d.ts +3 -0
  20. package/dist/core/src/rooms/RoomSessionRecording.d.ts.map +1 -1
  21. package/dist/core/src/rooms/index.d.ts +1 -0
  22. package/dist/core/src/rooms/index.d.ts.map +1 -1
  23. package/dist/core/src/rooms/methods.d.ts +11 -1
  24. package/dist/core/src/rooms/methods.d.ts.map +1 -1
  25. package/dist/core/src/types/index.d.ts +2 -2
  26. package/dist/core/src/types/index.d.ts.map +1 -1
  27. package/dist/core/src/types/utils.d.ts +60 -0
  28. package/dist/core/src/types/utils.d.ts.map +1 -1
  29. package/dist/core/src/types/video.d.ts +8 -5
  30. package/dist/core/src/types/video.d.ts.map +1 -1
  31. package/dist/core/src/types/videoMember.d.ts +60 -10
  32. package/dist/core/src/types/videoMember.d.ts.map +1 -1
  33. package/dist/core/src/types/videoPlayback.d.ts +110 -0
  34. package/dist/core/src/types/videoPlayback.d.ts.map +1 -0
  35. package/dist/core/src/types/videoRecording.d.ts +21 -5
  36. package/dist/core/src/types/videoRecording.d.ts.map +1 -1
  37. package/dist/core/src/types/videoRoomSession.d.ts +17 -1
  38. package/dist/core/src/types/videoRoomSession.d.ts.map +1 -1
  39. package/dist/core/src/utils/constants.d.ts +5 -0
  40. package/dist/core/src/utils/constants.d.ts.map +1 -1
  41. package/dist/core/src/utils/eventTransformUtils.d.ts +30 -0
  42. package/dist/core/src/utils/eventTransformUtils.d.ts.map +1 -0
  43. package/dist/core/src/utils/eventTransformUtils.test.d.ts +2 -0
  44. package/dist/core/src/utils/eventTransformUtils.test.d.ts.map +1 -0
  45. package/dist/core/src/utils/index.d.ts +8 -1
  46. package/dist/core/src/utils/index.d.ts.map +1 -1
  47. package/dist/core/src/utils/interfaces.d.ts +95 -4
  48. package/dist/core/src/utils/interfaces.d.ts.map +1 -1
  49. package/dist/core/src/utils/toExternalJSON.d.ts.map +1 -1
  50. package/dist/core/src/utils/toInternalEventName.d.ts.map +1 -1
  51. package/dist/index.esm.js +1 -1
  52. package/dist/index.esm.js.map +3 -3
  53. package/dist/index.js +1 -1
  54. package/dist/index.js.map +3 -3
  55. package/dist/index.umd.js +2 -2
  56. package/dist/index.umd.js.map +1 -1
  57. package/dist/js/src/BaseRoomSession.d.ts +60 -0
  58. package/dist/js/src/BaseRoomSession.d.ts.map +1 -0
  59. package/dist/js/src/Client.d.ts +6 -5
  60. package/dist/js/src/Client.d.ts.map +1 -1
  61. package/dist/js/src/JWTSession.d.ts.map +1 -1
  62. package/dist/js/src/RoomSession.d.ts +27 -0
  63. package/dist/js/src/RoomSession.d.ts.map +1 -0
  64. package/dist/js/src/RoomSessionDevice.d.ts +16 -0
  65. package/dist/js/src/RoomSessionDevice.d.ts.map +1 -0
  66. package/dist/js/src/RoomSessionScreenShare.d.ts +16 -0
  67. package/dist/js/src/RoomSessionScreenShare.d.ts.map +1 -0
  68. package/dist/js/src/createClient.d.ts +1 -1
  69. package/dist/js/src/createClient.d.ts.map +1 -1
  70. package/dist/js/src/createRoomObject.d.ts +10 -2
  71. package/dist/js/src/createRoomObject.d.ts.map +1 -1
  72. package/dist/js/src/features/mediaElements/mediaElementsSagas.d.ts +4 -4
  73. package/dist/js/src/features/mediaElements/mediaElementsSagas.d.ts.map +1 -1
  74. package/dist/js/src/index.d.ts +1 -1
  75. package/dist/js/src/index.d.ts.map +1 -1
  76. package/dist/js/src/joinRoom.d.ts +2 -1
  77. package/dist/js/src/joinRoom.d.ts.map +1 -1
  78. package/dist/js/src/utils/interfaces.d.ts +32 -8
  79. package/dist/js/src/utils/interfaces.d.ts.map +1 -1
  80. package/dist/js/src/video.d.ts +5 -5
  81. package/dist/js/src/video.d.ts.map +1 -1
  82. package/dist/js/tsconfig.build.tsbuildinfo +1 -1
  83. package/dist/webrtc/src/BaseConnection.d.ts +1 -1
  84. package/dist/webrtc/src/BaseConnection.d.ts.map +1 -1
  85. package/dist/webrtc/src/RTCPeer.d.ts +8 -1
  86. package/dist/webrtc/src/RTCPeer.d.ts.map +1 -1
  87. package/package.json +3 -3
  88. package/src/{Room.test.ts → BaseRoomSession.test.ts} +188 -5
  89. package/src/{Room.ts → BaseRoomSession.ts} +106 -60
  90. package/src/Client.ts +20 -12
  91. package/src/RoomSession.test.ts +28 -0
  92. package/src/RoomSession.ts +117 -0
  93. package/src/{RoomDevice.test.ts → RoomSessionDevice.test.ts} +7 -4
  94. package/src/{RoomDevice.ts → RoomSessionDevice.ts} +11 -8
  95. package/src/{RoomScreenShare.test.ts → RoomSessionScreenShare.test.ts} +7 -4
  96. package/src/{RoomScreenShare.ts → RoomSessionScreenShare.ts} +8 -5
  97. package/src/createClient.ts +7 -5
  98. package/src/createRoomObject.ts +36 -9
  99. package/src/features/mediaElements/mediaElementsSagas.ts +9 -18
  100. package/src/index.ts +5 -2
  101. package/src/joinRoom.ts +1 -0
  102. package/src/utils/interfaces.ts +38 -7
  103. package/src/video.ts +18 -5
  104. package/dist/js/src/Room.d.ts +0 -58
  105. package/dist/js/src/Room.d.ts.map +0 -1
  106. package/dist/js/src/RoomDevice.d.ts +0 -13
  107. package/dist/js/src/RoomDevice.d.ts.map +0 -1
  108. package/dist/js/src/RoomScreenShare.d.ts +0 -13
  109. package/dist/js/src/RoomScreenShare.d.ts.map +0 -1
@@ -1,19 +1,22 @@
1
1
  import { EventEmitter, actions } from '@signalwire/core'
2
- import { createRoomSessionObject } from './Room'
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: any
8
+ let room: RoomSession
8
9
 
9
10
  beforeEach(() => {
10
11
  store = configureJestStore()
11
- room = createRoomSessionObject({
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 = createRoomSessionObject({
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 = createRoomSessionObject({
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
- RoomObjectEvents,
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
- RoomScreenShareAPI,
32
- RoomScreenShareConnection,
33
- RoomScreenShare,
34
- } from './RoomScreenShare'
35
- import { RoomDeviceAPI, RoomDeviceConnection, RoomDevice } from './RoomDevice'
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 Room
44
+ export interface BaseRoomSession<T>
38
45
  extends RoomMethods,
39
- BaseConnectionContract<RoomObjectEvents> {
40
- join(): Promise<Room>
46
+ BaseConnectionContract<RoomSessionObjectEvents> {
47
+ join(): Promise<T>
41
48
  leave(): Promise<void>
42
49
  }
43
50
 
44
- export class RoomConnection
45
- extends BaseConnection<RoomObjectEvents>
51
+ export class RoomSessionConnection
52
+ extends BaseConnection<RoomSessionObjectEvents>
46
53
  implements BaseRoomInterface
47
54
  {
48
- private _screenShareList = new Set<RoomScreenShare>()
49
- private _deviceList = new Set<RoomDevice>()
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.__internal__.recording.start',
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?.recording,
81
- roomSessionId: this.roomSessionId,
82
- }
87
+ return toExternalJSON({
88
+ ...payload.recording,
89
+ room_session_id: this.roomSessionId,
90
+ })
83
91
  }
84
- return {
92
+
93
+ return toExternalJSON({
85
94
  id: payload.recording_id,
86
- roomSessionId: this.roomSessionId,
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 createScreenShareObject(opts: CreateScreenShareObjectOptions = {}) {
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<RoomObjectEvents> = {
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
- RoomScreenShareConnection,
119
- RoomScreenShare
156
+ RoomSessionScreenShareConnection,
157
+ RoomSessionScreenShare
120
158
  >({
121
159
  store: this.store,
122
- Component: RoomScreenShareAPI,
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<RoomObjectEvents> = {
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
- RoomDeviceConnection,
205
- RoomDevice
242
+ RoomSessionDeviceConnection,
243
+ RoomSessionDevice
206
244
  >({
207
245
  store: this.store,
208
- Component: RoomDeviceAPI,
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<Room>()
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 RoomAPI = extendComponent<RoomConnection, RoomMethods>(
280
- RoomConnection,
281
- {
282
- audioMute: Rooms.audioMuteMember,
283
- audioUnmute: Rooms.audioUnmuteMember,
284
- videoMute: Rooms.videoMuteMember,
285
- videoUnmute: Rooms.videoUnmuteMember,
286
- deaf: Rooms.deafMember,
287
- undeaf: Rooms.undeafMember,
288
- setMicrophoneVolume: Rooms.setInputVolumeMember,
289
- setSpeakerVolume: Rooms.setOutputVolumeMember,
290
- setInputSensitivity: Rooms.setInputSensitivityMember,
291
- removeMember: Rooms.removeMember,
292
- getMembers: Rooms.getMembers,
293
- getLayouts: Rooms.getLayouts,
294
- setLayout: Rooms.setLayout,
295
- hideVideoMuted: Rooms.hideVideoMuted,
296
- showVideoMuted: Rooms.showVideoMuted,
297
- getRecordings: Rooms.getRecordings,
298
- startRecording: Rooms.startRecording,
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 RoomObjectEventsHandlerMapping = RoomObjectEvents &
344
+ type RoomSessionObjectEventsHandlerMapping = RoomSessionObjectEvents &
303
345
  BaseConnectionStateEventTypes
304
346
 
305
347
  /** @internal */
306
- export const createRoomSessionObject = (
307
- params: BaseComponentOptions<RoomObjectEventsHandlerMapping>
308
- ): Room => {
309
- const room = connect<RoomObjectEventsHandlerMapping, RoomConnection, Room>({
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: RoomAPI,
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 { RoomConnection, createRoomSessionObject } from './Room'
10
+ import { RoomSession } from './RoomSession'
11
+ import {
12
+ createBaseRoomSessionObject,
13
+ RoomSessionConnection,
14
+ } from './BaseRoomSession'
11
15
 
12
- export interface Client extends ClientContract<Client, ClientEvents> {
13
- rooms: ClientAPI['rooms']
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
- rootElementId?: string
22
+ rootElement?: HTMLElement
18
23
  applyLocalVideoOverlay?: boolean
19
24
  stopCameraWhileMuted?: boolean
20
25
  stopMicrophoneWhileMuted?: boolean
21
26
  }
22
27
 
23
- export class ClientAPI extends BaseClient<ClientEvents> {
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
- rootElementId,
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<RoomConnection>> = []
42
+ const customSagas: Array<CustomSaga<RoomSessionConnection>> = []
36
43
 
37
44
  /**
38
- * If the user provides a `roomElementId` we'll automatically
39
- * handle the Audio and Video elements for them
45
+ * If the user provides a `roomElement` we'll
46
+ * automatically handle the Audio and Video elements
47
+ * for them
40
48
  */
41
- if (rootElementId) {
49
+ if (rootElement) {
42
50
  customSagas.push(
43
51
  makeMediaElementsSaga({
44
- rootElementId,
52
+ rootElement,
45
53
  applyLocalVideoOverlay,
46
54
  speakerId: options.speakerId,
47
55
  })
48
56
  )
49
57
  }
50
58
 
51
- const room = createRoomSessionObject({
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
+ })