@signalwire/js 3.7.1-dev.202201311747.da5ddf5.0 → 3.9.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 +25 -12
  2. package/dist/core/src/BaseComponent.d.ts.map +1 -1
  3. package/dist/core/src/BaseJWTSession.d.ts +1 -0
  4. package/dist/core/src/BaseJWTSession.d.ts.map +1 -1
  5. package/dist/core/src/BaseSession.d.ts +3 -0
  6. package/dist/core/src/BaseSession.d.ts.map +1 -1
  7. package/dist/core/src/chat/BaseChat.d.ts +3 -5
  8. package/dist/core/src/chat/BaseChat.d.ts.map +1 -1
  9. package/dist/core/src/chat/ChatMember.d.ts +6 -0
  10. package/dist/core/src/chat/ChatMember.d.ts.map +1 -1
  11. package/dist/core/src/chat/ChatMessage.d.ts +9 -0
  12. package/dist/core/src/chat/ChatMessage.d.ts.map +1 -1
  13. package/dist/core/src/chat/index.d.ts +1 -0
  14. package/dist/core/src/chat/index.d.ts.map +1 -1
  15. package/dist/core/src/chat/methods.d.ts +18 -15
  16. package/dist/core/src/chat/methods.d.ts.map +1 -1
  17. package/dist/core/src/chat/workers.d.ts +2 -1
  18. package/dist/core/src/chat/workers.d.ts.map +1 -1
  19. package/dist/core/src/index.d.ts +3 -3
  20. package/dist/core/src/index.d.ts.map +1 -1
  21. package/dist/core/src/redux/actions.d.ts +6 -4
  22. package/dist/core/src/redux/actions.d.ts.map +1 -1
  23. package/dist/core/src/redux/features/pubSub/pubSubSaga.d.ts.map +1 -1
  24. package/dist/core/src/redux/features/session/sessionSlice.d.ts +5 -5
  25. package/dist/core/src/redux/index.d.ts +4 -1
  26. package/dist/core/src/redux/index.d.ts.map +1 -1
  27. package/dist/core/src/redux/interfaces.d.ts +4 -3
  28. package/dist/core/src/redux/interfaces.d.ts.map +1 -1
  29. package/dist/core/src/redux/rootReducer.d.ts +1 -1
  30. package/dist/core/src/redux/rootSaga.d.ts +16 -7
  31. package/dist/core/src/redux/rootSaga.d.ts.map +1 -1
  32. package/dist/core/src/rooms/methods.d.ts +45 -22
  33. package/dist/core/src/rooms/methods.d.ts.map +1 -1
  34. package/dist/core/src/testUtils.d.ts +4 -1
  35. package/dist/core/src/testUtils.d.ts.map +1 -1
  36. package/dist/core/src/types/chat.d.ts +11 -6
  37. package/dist/core/src/types/chat.d.ts.map +1 -1
  38. package/dist/core/src/types/index.d.ts +1 -0
  39. package/dist/core/src/types/index.d.ts.map +1 -1
  40. package/dist/core/src/types/video.d.ts +2 -0
  41. package/dist/core/src/types/video.d.ts.map +1 -1
  42. package/dist/core/src/types/videoLayout.d.ts +2 -0
  43. package/dist/core/src/types/videoLayout.d.ts.map +1 -1
  44. package/dist/core/src/types/videoMember.d.ts +10 -1
  45. package/dist/core/src/types/videoMember.d.ts.map +1 -1
  46. package/dist/core/src/types/videoRoomSession.d.ts +1 -3
  47. package/dist/core/src/types/videoRoomSession.d.ts.map +1 -1
  48. package/dist/core/src/utils/constants.d.ts +1 -0
  49. package/dist/core/src/utils/constants.d.ts.map +1 -1
  50. package/dist/core/src/utils/index.d.ts +5 -1
  51. package/dist/core/src/utils/index.d.ts.map +1 -1
  52. package/dist/core/src/utils/interfaces.d.ts +17 -8
  53. package/dist/core/src/utils/interfaces.d.ts.map +1 -1
  54. package/dist/core/src/utils/proxyUtils.d.ts +5 -0
  55. package/dist/core/src/utils/proxyUtils.d.ts.map +1 -1
  56. package/dist/index.esm.js +188 -52
  57. package/dist/index.esm.js.map +3 -3
  58. package/dist/index.js +231 -103
  59. package/dist/index.js.map +3 -3
  60. package/dist/index.umd.js +2 -2
  61. package/dist/index.umd.js.map +1 -1
  62. package/dist/js/src/BaseRoomSession.d.ts +7 -0
  63. package/dist/js/src/BaseRoomSession.d.ts.map +1 -1
  64. package/dist/js/src/JWTSession.d.ts.map +1 -1
  65. package/dist/js/src/RoomSession.d.ts.map +1 -1
  66. package/dist/js/src/RoomSession.docs.d.ts +21 -8
  67. package/dist/js/src/RoomSession.docs.d.ts.map +1 -1
  68. package/dist/js/src/chat/Client.d.ts +37 -3
  69. package/dist/js/src/chat/Client.d.ts.map +1 -1
  70. package/dist/js/src/chat/Client.docs.d.ts +238 -0
  71. package/dist/js/src/chat/Client.docs.d.ts.map +1 -0
  72. package/dist/js/src/chat/index.d.ts +5 -0
  73. package/dist/js/src/chat/index.d.ts.map +1 -1
  74. package/dist/js/src/index.d.ts +13 -9
  75. package/dist/js/src/index.d.ts.map +1 -1
  76. package/dist/js/src/testUtils.d.ts +8 -2
  77. package/dist/js/src/testUtils.d.ts.map +1 -1
  78. package/dist/js/src/utils/interfaces.d.ts +18 -2
  79. package/dist/js/src/utils/interfaces.d.ts.map +1 -1
  80. package/dist/js/src/video/memberListUpdatedWorker.d.ts +14 -0
  81. package/dist/js/src/video/memberListUpdatedWorker.d.ts.map +1 -0
  82. package/dist/js/src/video/workers.d.ts +2 -0
  83. package/dist/js/src/video/workers.d.ts.map +1 -0
  84. package/dist/js/src/video.d.ts +3 -3
  85. package/dist/js/src/video.d.ts.map +1 -1
  86. package/dist/js/src/webrtc.d.ts +1 -1
  87. package/dist/js/src/webrtc.d.ts.map +1 -1
  88. package/dist/js/tsconfig.build.tsbuildinfo +1 -1
  89. package/dist/webrtc/src/BaseConnection.d.ts.map +1 -1
  90. package/dist/webrtc/src/index.d.ts +1 -1
  91. package/dist/webrtc/src/index.d.ts.map +1 -1
  92. package/dist/webrtc/src/utils/deviceHelpers.d.ts +45 -0
  93. package/dist/webrtc/src/utils/deviceHelpers.d.ts.map +1 -1
  94. package/dist/webrtc/src/utils/interfaces.d.ts +3 -0
  95. package/dist/webrtc/src/utils/interfaces.d.ts.map +1 -1
  96. package/package.json +3 -3
  97. package/src/BaseRoomSession.test.ts +2 -2
  98. package/src/BaseRoomSession.ts +26 -1
  99. package/src/RoomSession.docs.ts +61 -13
  100. package/src/RoomSession.ts +18 -4
  101. package/src/chat/Client.docs.ts +259 -0
  102. package/src/chat/Client.ts +37 -10
  103. package/src/chat/index.ts +10 -0
  104. package/src/index.ts +14 -10
  105. package/src/utils/interfaces.ts +25 -2
  106. package/src/video/memberListUpdatedWorker.ts +217 -0
  107. package/src/video/workers.ts +1 -0
  108. package/src/video.ts +3 -2
  109. package/src/webrtc.ts +1 -0
@@ -41,6 +41,7 @@ import {
41
41
  RoomSessionDeviceConnection,
42
42
  RoomSessionDevice,
43
43
  } from './RoomSessionDevice'
44
+ import * as workers from './video/workers'
44
45
 
45
46
  export interface BaseRoomSession<T>
46
47
  extends RoomMethods,
@@ -120,6 +121,20 @@ export class RoomSessionConnection
120
121
  ])
121
122
  }
122
123
 
124
+ /**
125
+ * This method will be called by `join()` right before the
126
+ * `connect()` happens and it's a way for us to control
127
+ * exactly when the workers are attached.
128
+ * @internal
129
+ */
130
+ protected attachPreConnectWorkers() {
131
+ this.setWorker('memberListUpdated', {
132
+ worker: workers.memberListUpdatedWorker,
133
+ })
134
+
135
+ this.attachWorkers()
136
+ }
137
+
123
138
  /** @deprecated Use {@link startScreenShare} instead. */
124
139
  async createScreenShareObject(opts: CreateScreenShareObjectOptions = {}) {
125
140
  return this.startScreenShare(opts)
@@ -129,7 +144,13 @@ export class RoomSessionConnection
129
144
  * Allow sharing the screen within the room.
130
145
  */
131
146
  async startScreenShare(opts: StartScreenShareOptions = {}) {
132
- const { autoJoin = true, audio = false, video = true } = opts
147
+ const {
148
+ autoJoin = true,
149
+ audio = false,
150
+ video = true,
151
+ layout,
152
+ positions,
153
+ } = opts
133
154
  const displayStream: MediaStream = await getDisplayMedia({
134
155
  audio: audio === true ? SCREENSHARE_AUDIO_CONSTRAINTS : audio,
135
156
  video,
@@ -145,6 +166,8 @@ export class RoomSessionConnection
145
166
  memberCallId: this.__uuid,
146
167
  memberId: this.memberId,
147
168
  },
169
+ layout,
170
+ positions,
148
171
  }
149
172
 
150
173
  const screenShare = connect<
@@ -329,6 +352,8 @@ export const RoomSessionAPI = extendComponent<
329
352
  getMembers: Rooms.getMembers,
330
353
  getLayouts: Rooms.getLayouts,
331
354
  setLayout: Rooms.setLayout,
355
+ // setPositions: Rooms.setPositions,
356
+ // setMemberPosition: Rooms.setMemberPosition,
332
357
  hideVideoMuted: Rooms.hideVideoMuted,
333
358
  showVideoMuted: Rooms.showVideoMuted,
334
359
  getRecordings: Rooms.getRecordings,
@@ -1,14 +1,15 @@
1
- import type { Rooms } from '@signalwire/core'
1
+ import type { AssertSameType, VideoPositions, Rooms } from '@signalwire/core'
2
2
  import { BaseRoomSession } from './BaseRoomSession'
3
3
  import { RoomSessionDevice } from './RoomSessionDevice'
4
4
  import { RoomSessionScreenShare } from './RoomSessionScreenShare'
5
+ import { StartScreenShareOptions } from './utils/interfaces'
5
6
 
6
7
  export interface RoomSessionDocs<T>
7
8
  extends RoomMemberMethodsInterfaceDocs,
8
9
  RoomControlMethodsInterfaceDocs,
9
10
  RoomLayoutMethodsInterface,
10
11
  RoomSessionConstructorDocs<T>,
11
- Pick<BaseRoomSession<T>, 'on' | 'off' | 'once'> {
12
+ Pick<BaseRoomSession<T>, 'on' | 'off' | 'once' | 'removeAllListeners'> {
12
13
  /** @internal */
13
14
  stopOutboundAudio(): void
14
15
  /** @internal */
@@ -116,17 +117,26 @@ export interface RoomSessionDocs<T>
116
117
  *
117
118
  * @example Sharing the screen together with the associated audio:
118
119
  * ```typescript
119
- * await roomSession.startScreenShare({audio: true, video: true})
120
+ * await roomSession.startScreenShare({ audio: true, video: true })
120
121
  * ```
121
122
  */
122
- startScreenShare(opts: {
123
- /** Whether the screen share object should automatically join the room */
124
- autoJoin?: boolean
125
- /** Audio constraints to use when joining the room. Default: `true`. */
126
- audio?: MediaStreamConstraints['audio']
127
- /** Video constraints to use when joining the room. Default: `true`. */
128
- video?: MediaStreamConstraints['video']
129
- }): Promise<RoomSessionScreenShare>
123
+ startScreenShare(
124
+ opts: AssertSameType<
125
+ StartScreenShareOptions,
126
+ {
127
+ /** Whether the screen share object should automatically join the room. Default: `true`. */
128
+ autoJoin?: boolean
129
+ /** Audio constraints to use when joining the room. Default: `false`. */
130
+ audio?: MediaStreamConstraints['audio']
131
+ /** Video constraints to use when joining the room. Default: `true`. */
132
+ video?: MediaStreamConstraints['video']
133
+ /** Layout to use to use when joining the room. */
134
+ layout?: string
135
+ /** Automatically set positions when screen share joins the room. */
136
+ positions?: VideoPositions
137
+ }
138
+ >
139
+ ): Promise<RoomSessionScreenShare>
130
140
 
131
141
  /**
132
142
  * Adds a camera device to the room. Using this method, a user can stream
@@ -839,6 +849,10 @@ interface RoomControlMethodsInterfaceDocs {
839
849
  play(params: {
840
850
  url: string
841
851
  volume?: number
852
+ // positions?: Record<
853
+ // string,
854
+ // 'self' | 'standard' | `standard-${number}` | 'off-canvas'
855
+ // >
842
856
  }): Promise<Rooms.RoomSessionPlayback>
843
857
  }
844
858
 
@@ -887,7 +901,32 @@ interface RoomLayoutMethodsInterface {
887
901
  * await room.setLayout({name: "6x6"})
888
902
  * ```
889
903
  */
890
- setLayout(params: { name: string }): Rooms.SetLayout
904
+ setLayout(params: {
905
+ name: string
906
+ // positions?: Record<
907
+ // string,
908
+ // 'self' | 'standard' | `standard-${number}` | 'off-canvas'
909
+ // >
910
+ }): Rooms.SetLayout
911
+
912
+ // setPositions(params: {
913
+ // positions: Record<
914
+ // string,
915
+ // | 'self'
916
+ // | 'standard'
917
+ // | `standard-${number}`
918
+ // | 'off-canvas'
919
+ // >
920
+ // }): Promise<void>
921
+
922
+ // setMemberPosition(params: {
923
+ // memberId?: string
924
+ // position:
925
+ // | 'self'
926
+ // | 'standard'
927
+ // | `standard-${number}`
928
+ // | 'off-canvas'
929
+ // }): Promise<void>
891
930
  }
892
931
 
893
932
  /**
@@ -902,7 +941,7 @@ export interface RoomSessionEvents {
902
941
  *
903
942
  * ```typescript
904
943
  * type _ = {
905
- * room: {
944
+ * room_session: {
906
945
  * room_session_id: string,
907
946
  * logos_visible: boolean,
908
947
  * members: Array<{
@@ -1094,6 +1133,15 @@ export interface RoomSessionEvents {
1094
1133
  */
1095
1134
  'member.talking': undefined
1096
1135
 
1136
+ /**
1137
+ * The set of members or one or more properties of a member have changed. The
1138
+ * event handler receives an object `e` with the updated, full list of members in
1139
+ * the room as `e.members`.
1140
+ *
1141
+ * @event
1142
+ */
1143
+ 'memberList.updated': undefined
1144
+
1097
1145
  /**
1098
1146
  * The layout of the room has changed. This event is not limited to changes
1099
1147
  * associated to the grid layout of the room: it also includes for example
@@ -1,4 +1,8 @@
1
- import { UserOptions, AssertSameType, getLogger } from '@signalwire/core'
1
+ import {
2
+ UserOptions,
3
+ AssertSameType,
4
+ getLogger,
5
+ } from '@signalwire/core'
2
6
  import { createClient } from './createClient'
3
7
  import type { MakeRoomOptions } from './Client'
4
8
  import { BaseRoomSession } from './BaseRoomSession'
@@ -27,6 +31,8 @@ export const UNSAFE_PROP_ACCESS = [
27
31
  'setInputSensitivity',
28
32
  'setInputVolume',
29
33
  'setLayout',
34
+ 'setPositions',
35
+ 'setMemberPosition',
30
36
  'setOutputVolume',
31
37
  'showVideoMuted',
32
38
  'startRecording',
@@ -123,6 +129,9 @@ export const RoomSession = function (roomOptions: RoomSessionOptions) {
123
129
  const join = () => {
124
130
  return new Promise(async (resolve, reject) => {
125
131
  try {
132
+ // @ts-expect-error
133
+ room.attachPreConnectWorkers()
134
+
126
135
  await client.connect()
127
136
 
128
137
  room.once('room.subscribed', () => {
@@ -137,10 +146,15 @@ export const RoomSession = function (roomOptions: RoomSessionOptions) {
137
146
  })
138
147
  }
139
148
 
149
+ const interceptors = {
150
+ join,
151
+ } as const
152
+
140
153
  return new Proxy<Omit<RoomSession, 'new'>>(room, {
141
- get(target: RoomSession, prop: any, receiver: any) {
142
- if (prop === 'join') {
143
- return join
154
+ get(target: RoomSession, prop: keyof RoomSession, receiver: any) {
155
+ if (prop in interceptors) {
156
+ // @ts-expect-error
157
+ return interceptors[prop]
144
158
  }
145
159
 
146
160
  if (!target.active && UNSAFE_PROP_ACCESS.includes(prop)) {
@@ -0,0 +1,259 @@
1
+ import type { ConsumerContract, Chat } from '@signalwire/core'
2
+
3
+ import type { ClientApiEvents, ClientFullState } from './Client'
4
+
5
+ export type PagingCursor =
6
+ | {
7
+ before: string
8
+ after?: never
9
+ }
10
+ | {
11
+ before?: never
12
+ after: string
13
+ }
14
+
15
+ export interface ClientDocs
16
+ extends Omit<
17
+ ConsumerContract<ClientApiEvents, ClientFullState>,
18
+ 'subscribe'
19
+ > {
20
+ /**
21
+ * Creates a new Chat client.
22
+ *
23
+ * @example
24
+ *
25
+ * ```js
26
+ * import { Chat } from '@signalwire/js'
27
+ *
28
+ * const chatClient = new Chat.Client({
29
+ * token: '<your_chat_token>',
30
+ * })
31
+ * ```
32
+ */
33
+ new (chatOptions: {
34
+ /** SignalWire Chat token (you can get one with the REST APIs) */
35
+ token: string
36
+ /** @ignore */
37
+ logLevel?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent'
38
+ }): this
39
+
40
+ /**
41
+ * Replaces the token used by the client with a new one. You can use this
42
+ * method to replace the token when for example it is expiring, in order to
43
+ * keep the session alive.
44
+ *
45
+ * The new token can contain different channels from the previous one. In that
46
+ * case, you will need to subscribe to the new channels if you want to receive
47
+ * messages for those. Channels that were in the previous token but are not in
48
+ * the new one will get unsubscribed automatically.
49
+ *
50
+ * @param token the new token.
51
+ *
52
+ * @example
53
+ * ```js
54
+ * const chatClient = new Chat.Client({
55
+ * token: '<your chat token>'
56
+ * })
57
+ *
58
+ * chatClient.on('session.expiring', async () => {
59
+ * const newToken = await fetchNewToken(..)
60
+ *
61
+ * await chatClient.updateToken(newToken)
62
+ * })
63
+ * ```
64
+ */
65
+ updateToken(token: string): Promise<void>
66
+
67
+ /**
68
+ * List of channels for which you want to receive messages. You can only
69
+ * subscribe to those channels for which your token has read permission.
70
+ *
71
+ * Note that the `subscribe` function is idempotent, and calling it again with
72
+ * a different set of channels _will not_ unsubscribe you from the old ones.
73
+ * To unsubscribe, use {@link unsubscribe}.
74
+ *
75
+ * @param channels the channels to subscribe to, either in the form of a
76
+ * string (for one channel) or an array of strings.
77
+ *
78
+ * @example
79
+ * ```js
80
+ * const chatClient = new Chat.Client({
81
+ * token: '<your chat token>'
82
+ * })
83
+ *
84
+ * chatClient.on('message', m => console.log(m))
85
+ *
86
+ * await chatClient.subscribe("my-channel")
87
+ * await chatClient.subscribe(["chan-2", "chan-3"])
88
+ * ```
89
+ */
90
+ subscribe(channels: string | string[]): Promise<any>
91
+
92
+ /**
93
+ * List of channels from which you want to unsubscribe.
94
+ *
95
+ * @param channels the channels to unsubscribe from, either in the form of a
96
+ * string (for one channel) or an array of strings.
97
+ *
98
+ * @example
99
+ * ```js
100
+ * await chatClient.unsubscribe("my-channel")
101
+ * await chatClient.unsubscribe(["chan-2", "chan-3"])
102
+ * ```
103
+ */
104
+ unsubscribe(channels: string | string[]): Promise<any>
105
+
106
+ /**
107
+ * Publish a message into the specified channel.
108
+ *
109
+ * @example Publishing a message as a string:
110
+ * ```js
111
+ * await chatClient.publish({
112
+ * channel: 'my-channel',
113
+ * content: 'Hello, world.'
114
+ * })
115
+ * ```
116
+ *
117
+ * @example Publishing a message as an object:
118
+ * ```js
119
+ * await chatClient.publish({
120
+ * channel: 'my-channel',
121
+ * content: {
122
+ * field_one: 'value_one',
123
+ * field_two: 'value_two',
124
+ * }
125
+ * })
126
+ * ```
127
+ */
128
+ publish(params: {
129
+ /** The message to send. This can be any JSON-serializable object. */
130
+ content: any
131
+ /** Channel in which to send the message. */
132
+ channel: string
133
+ /**
134
+ * Metadata associated with the message. There are no requirements on the
135
+ * content of metadata.
136
+ */
137
+ meta?: Record<any, any>
138
+ }): Promise<any>
139
+
140
+ /**
141
+ * Returns the list of messages that were sent to the specified channel.
142
+ *
143
+ * @example
144
+ * ```js
145
+ * const m = await chatClient.getMessages({ channel: 'chan1' })
146
+ *
147
+ * m.messages.length; // 23
148
+ * m.messages[0]; // the most recent message
149
+ * m.messages[0].member; // the sender
150
+ * m.messages[0].content; // the content
151
+ * m.messages[0].meta; // the metadata (if any)
152
+ *
153
+ * m.cursor.next; // if not null, there are more messages.
154
+ *
155
+ * // Get the next page using the cursor
156
+ * const next = await chatClient.getMessages({
157
+ * channel: 'chan1',
158
+ * cursor: {
159
+ * after: m.cursor.after
160
+ * }
161
+ * })
162
+ * ```
163
+ */
164
+ getMessages(params: {
165
+ /** Channel for which to retrieve the messages. */
166
+ channel: string
167
+ /** Cursor for pagination. */
168
+ cursor?: PagingCursor
169
+ }): Promise<any>
170
+
171
+ /**
172
+ * Returns the list of members in the given channel.
173
+ *
174
+ * @example
175
+ * ```js
176
+ * const m = await chatClient.getMembers({ channel: 'my-channel' })
177
+ *
178
+ * m.members.length; // 7
179
+ * m.members[0]; // { id: ..., channel: ..., state: ... }
180
+ * ```
181
+ */
182
+ getMembers(params: {
183
+ /** The channel for which to get the list of members. */
184
+ channel: string
185
+ }): Promise<any>
186
+
187
+ /**
188
+ * Sets a state object for the current member, for the specified channels. The
189
+ * previous state object will be completely replaced.
190
+ *
191
+ * @example
192
+ * ```js
193
+ * await chatClient.setMemberState({
194
+ * channels: ['chan1', 'chan2'],
195
+ * state: {
196
+ * online: true,
197
+ * typing: false
198
+ * }
199
+ * })
200
+ * ```
201
+ */
202
+ setMemberState(params: {
203
+ /** Channels for which to set the state. */
204
+ channels: string | string[]
205
+ /**
206
+ * The state to set. There are no requirements on the content of the state.
207
+ */
208
+ state: Record<any, any>
209
+ }): Promise<any>
210
+
211
+ /**
212
+ * Returns the states of a member in the specified channels.
213
+ *
214
+ * @example
215
+ * ```js
216
+ * const s = await chatClient.getMemberState({
217
+ * channels: ['chan1', 'chan2'],
218
+ * memberId: 'my-member-id'
219
+ * })
220
+ *
221
+ * s.channels.length; // 2
222
+ * s.channels.chan1.state; // the state object for chan1
223
+ * ```
224
+ */
225
+ getMemberState(params: {
226
+ /** Channels for which to get the state. */
227
+ channels: string | string[]
228
+ /** Id of the member for which to get the state. */
229
+ memberId: string
230
+ }): Promise<any>
231
+ }
232
+
233
+ export interface ClientApiEventsDocs {
234
+ /**
235
+ * The session is going to expire.
236
+ * Use the `updateToken` method to refresh your token.
237
+ */
238
+ 'session.expiring': () => void
239
+
240
+ /**
241
+ * A new message has been received.
242
+ */
243
+ message: (message: Chat.ChatMessage) => void
244
+
245
+ /**
246
+ * A new member joined the chat.
247
+ */
248
+ 'member.joined': (member: Chat.ChatMember) => void
249
+
250
+ /**
251
+ * A member updated its state.
252
+ */
253
+ 'member.updated': (member: Chat.ChatMember) => void
254
+
255
+ /**
256
+ * A member left the chat.
257
+ */
258
+ 'member.left': (member: Chat.ChatMember) => void
259
+ }
@@ -5,29 +5,56 @@ import type {
5
5
  UserOptions,
6
6
  Chat as ChatNamespace,
7
7
  } from '@signalwire/core'
8
- import { getLogger } from '@signalwire/core'
9
8
  import { createClient } from '../createClient'
9
+ import { ClientApiEventsDocs, ClientDocs } from './Client.docs'
10
10
 
11
- export interface ClientApiEvents extends ChatNamespace.BaseChatApiEvents {}
11
+ interface ClientApiEventsMain extends ChatNamespace.BaseChatApiEvents {}
12
+ export interface ClientApiEvents
13
+ extends AssertSameType<ClientApiEventsMain, ClientApiEventsDocs> {}
12
14
 
15
+ /** @ignore */
13
16
  export interface ClientFullState extends Client {}
14
17
  interface ClientMain
15
18
  extends ChatContract,
16
19
  Omit<ConsumerContract<ClientApiEvents, ClientFullState>, 'subscribe'> {}
17
20
 
18
- interface ClientDocs extends ClientMain {}
19
-
21
+ /**
22
+ * You can use the Client object to build a messaging system into the browser.
23
+ *
24
+ * Example usage:
25
+ *
26
+ * ```js
27
+ * import { Chat } from '@signalwire/js'
28
+ *
29
+ * const chatClient = new Chat.Client({
30
+ * token: '<your_chat_token>', // get this from the REST APIs
31
+ * })
32
+ *
33
+ * await chatClient.subscribe([ 'mychannel1', 'mychannel2' ])
34
+ *
35
+ * chatClient.on('message', (message) => {
36
+ * console.log("Received", message.content,
37
+ * "on", message.channel,
38
+ * "at", message.publishedAt)
39
+ * })
40
+ *
41
+ * await chatClient.publish({
42
+ * channel: 'mychannel1',
43
+ * content: 'hello world'
44
+ * })
45
+ * ```
46
+ *
47
+ * ## Events
48
+ *
49
+ * Please see {@link ClientApiEvents} for the list of events emitted by a chat
50
+ * Client object.
51
+ */
20
52
  export interface Client extends AssertSameType<ClientMain, ClientDocs> {}
21
53
 
54
+ /** @ignore */
22
55
  export interface ClientOptions extends UserOptions {}
23
56
 
24
57
  export const Client = function (chatOptions: ClientOptions) {
25
- if ('production' === process.env.NODE_ENV) {
26
- getLogger().warn(
27
- '`Chat` is still under development and may change in the future without prior notice.'
28
- )
29
- }
30
-
31
58
  const client = createClient<Client>(chatOptions)
32
59
  const subscribe: Client['subscribe'] = async (channels) => {
33
60
  await client.connect()
package/src/chat/index.ts CHANGED
@@ -1 +1,11 @@
1
+ import { Chat } from '@signalwire/core'
2
+ import ChatMember = Chat.ChatMember
3
+ import ChatMessage = Chat.ChatMessage
4
+
1
5
  export * from './Client'
6
+ export { PagingCursor } from './Client.docs'
7
+
8
+ export {
9
+ ChatMember,
10
+ ChatMessage,
11
+ }
package/src/index.ts CHANGED
@@ -2,18 +2,19 @@
2
2
  * Welcome to the technical documentation for the JavaScript SDK.
3
3
  *
4
4
  * At the outer level, when you import the SignalWire JS library you get access
5
- * to two different namespaces:
5
+ * to three different namespaces:
6
6
  *
7
7
  * - {@link Video}
8
+ * - {@link Chat}
8
9
  * - {@link WebRTC}
9
10
  *
10
- * {@link Video} gives you access to the classes and methods that let you
11
- * interface with the backend Video APIs. {@link WebRTC} contains several
12
- * functions that are useful for interacting with the hardware of the user's
13
- * device.
11
+ * Video gives you access to the classes and methods that let you
12
+ * interface with the backend Video APIs. Chat gives you access to the classes and functions that you need to create a real-time chat application. WebRTC
13
+ * contains several functions that are useful for interacting with the hardware of the user's device.
14
+ *
14
15
  *
15
- * You don't know where to start? Create an instance of
16
- * {@link Video.RoomSession} to join a room, or take a look at [Getting Started
16
+ * Don't know where to start? Create an instance of
17
+ * {@link Video.RoomSession} to join a room, use the {@link Chat.Client} constructor to start a chat application, or take a look at [Getting Started
17
18
  * with the SignalWire Video
18
19
  * API](https://developer.signalwire.com/apis/docs/getting-started-with-the-signalwire-video-api-1).
19
20
  *
@@ -46,6 +47,12 @@ export type RoomScreenShare = VideoMemberEntity & { type: 'screen' }
46
47
  /** @ignore @deprecated */
47
48
  export type RoomDevice = VideoMemberEntity & { type: 'device' }
48
49
 
50
+ /**
51
+ * The Chat namespace contains the classes and functions that you need to
52
+ * create a real-time chat application.
53
+ */
54
+ export * as Chat from './chat'
55
+
49
56
  /**
50
57
  * The Video namespace contains the classes and functions that you need to
51
58
  * create a video conferencing application.
@@ -96,6 +103,3 @@ export type {
96
103
  RoomSessionObjectEventsHandlerMap as RoomObjectEventsHandlerMap,
97
104
  RoomSessionObjectEvents as RoomObjectEvents,
98
105
  } from './utils/interfaces'
99
-
100
- /** @internal */
101
- export * as __sw__Chat from './chat'
@@ -5,7 +5,6 @@ import type {
5
5
  VideoLayoutEventNames,
6
6
  VideoRoomSessionEventNames,
7
7
  VideoRoomEventParams,
8
- VideoMemberEntity,
9
8
  InternalVideoMemberEntity,
10
9
  VideoMemberEventNames,
11
10
  MemberUpdated,
@@ -22,6 +21,8 @@ import type {
22
21
  VideoRoomSessionContract,
23
22
  OnlyFunctionProperties,
24
23
  AssertSameType,
24
+ MemberListUpdated,
25
+ VideoPositions,
25
26
  } from '@signalwire/core'
26
27
  import { INTERNAL_MEMBER_UPDATABLE_PROPS } from '@signalwire/core'
27
28
  import type { RoomSession } from '../RoomSession'
@@ -29,6 +30,18 @@ import type { RoomSessionDevice } from '../RoomSessionDevice'
29
30
  import type { RoomSessionScreenShare } from '../RoomSessionScreenShare'
30
31
  import { RoomMemberSelfMethodsInterfaceDocs } from './interfaces.docs'
31
32
 
33
+ /**
34
+ * @privateRemarks
35
+ * Every other package exposing a `VideoMemberEntity` is
36
+ * transforming the server payload into something else, with
37
+ * the most significant change being converting properties
38
+ * from snake to camel case. The `js` package, on the other
39
+ * hand, exposes the server payload pretty much as is (as as
40
+ * v3) so what we consider internal (sdk and server) in
41
+ * other packages is external (user facing) for `js`.
42
+ */
43
+ type VideoMemberEntity = InternalVideoMemberEntity
44
+
32
45
  const INTERNAL_MEMBER_UPDATED_EVENTS = Object.keys(
33
46
  INTERNAL_MEMBER_UPDATABLE_PROPS
34
47
  ).map((key) => {
@@ -47,19 +60,27 @@ export type VideoMemberHandlerParams = { member: VideoMemberEntity }
47
60
  export type VideoMemberUpdatedHandlerParams = {
48
61
  member: VideoMemberEntityUpdated
49
62
  }
63
+ export type VideoMemberListUpdatedParams = { members: VideoMemberEntity[] }
50
64
 
51
65
  export type RoomSessionObjectEventsHandlerMap = Record<
52
66
  VideoLayoutEventNames,
53
67
  (params: { layout: VideoLayout }) => void
54
68
  > &
55
69
  Record<
56
- Exclude<VideoMemberEventNames, MemberUpdated | MemberUpdatedEventNames>,
70
+ Exclude<
71
+ VideoMemberEventNames,
72
+ MemberUpdated | MemberUpdatedEventNames | MemberListUpdated
73
+ >,
57
74
  (params: VideoMemberHandlerParams) => void
58
75
  > &
59
76
  Record<
60
77
  Extract<VideoMemberEventNames, MemberUpdated | MemberUpdatedEventNames>,
61
78
  (params: VideoMemberUpdatedHandlerParams) => void
62
79
  > &
80
+ Record<
81
+ Extract<VideoMemberEventNames, MemberListUpdated>,
82
+ (params: VideoMemberListUpdatedParams) => void
83
+ > &
63
84
  Record<
64
85
  DeprecatedMemberUpdatableProps,
65
86
  (params: DeprecatedVideoMemberHandlerParams) => void
@@ -82,6 +103,8 @@ export type StartScreenShareOptions = {
82
103
  autoJoin?: boolean
83
104
  audio?: MediaStreamConstraints['audio']
84
105
  video?: MediaStreamConstraints['video']
106
+ layout?: string
107
+ positions?: VideoPositions
85
108
  }
86
109
 
87
110
  /**