@signalwire/js 3.6.0 → 3.7.1-dev.202201180939.d2ef427.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 +5 -25
- package/dist/core/src/BaseComponent.d.ts.map +1 -1
- package/dist/core/src/BaseSession.d.ts +4 -2
- package/dist/core/src/BaseSession.d.ts.map +1 -1
- package/dist/core/src/chat/BaseChat.d.ts +4 -4
- package/dist/core/src/chat/BaseChat.d.ts.map +1 -1
- package/dist/core/src/chat/ChatMember.d.ts +9 -0
- package/dist/core/src/chat/ChatMember.d.ts.map +1 -0
- package/dist/core/src/chat/ChatMessage.d.ts +4 -4
- package/dist/core/src/chat/ChatMessage.d.ts.map +1 -1
- package/dist/core/src/chat/methods.d.ts +14 -0
- package/dist/core/src/chat/methods.d.ts.map +1 -1
- package/dist/core/src/chat/utils/index.d.ts +3 -0
- package/dist/core/src/chat/utils/index.d.ts.map +1 -0
- package/dist/core/src/chat/utils/toInternalChatChannels.d.ts +3 -0
- package/dist/core/src/chat/utils/toInternalChatChannels.d.ts.map +1 -0
- package/dist/core/src/chat/utils/toInternalChatChannels.test.d.ts +2 -0
- package/dist/core/src/chat/utils/toInternalChatChannels.test.d.ts.map +1 -0
- package/dist/core/src/chat/workers.d.ts.map +1 -1
- package/dist/core/src/internal/BaseBackendSession.d.ts.map +1 -1
- package/dist/core/src/internal/InternalRPC.d.ts +7 -7
- package/dist/core/src/internal/InternalRPC.d.ts.map +1 -1
- package/dist/core/src/redux/actions.d.ts +14 -14
- package/dist/core/src/redux/actions.d.ts.map +1 -1
- package/dist/core/src/redux/connect.d.ts.map +1 -1
- package/dist/core/src/redux/features/component/componentSaga.d.ts +4 -0
- package/dist/core/src/redux/features/component/componentSaga.d.ts.map +1 -0
- package/dist/core/src/redux/features/component/componentSaga.test.d.ts +2 -0
- package/dist/core/src/redux/features/component/componentSaga.test.d.ts.map +1 -0
- package/dist/core/src/redux/features/component/componentSelectors.d.ts +6 -2
- package/dist/core/src/redux/features/component/componentSelectors.d.ts.map +1 -1
- package/dist/core/src/redux/features/component/componentSelectors.test.d.ts +2 -0
- package/dist/core/src/redux/features/component/componentSelectors.test.d.ts.map +1 -0
- package/dist/core/src/redux/features/component/componentSlice.d.ts +3955 -9
- package/dist/core/src/redux/features/component/componentSlice.d.ts.map +1 -1
- package/dist/core/src/redux/features/executeQueue/executeQueueSlice.d.ts +44 -7
- package/dist/core/src/redux/features/executeQueue/executeQueueSlice.d.ts.map +1 -1
- package/dist/core/src/redux/features/session/sessionSaga.d.ts.map +1 -1
- package/dist/core/src/redux/features/session/sessionSlice.d.ts +74 -8
- package/dist/core/src/redux/features/session/sessionSlice.d.ts.map +1 -1
- package/dist/core/src/redux/index.d.ts +6 -25
- package/dist/core/src/redux/index.d.ts.map +1 -1
- package/dist/core/src/redux/interfaces.d.ts +2 -1
- package/dist/core/src/redux/interfaces.d.ts.map +1 -1
- package/dist/core/src/redux/rootReducer.d.ts +417 -3
- package/dist/core/src/redux/rootReducer.d.ts.map +1 -1
- package/dist/core/src/redux/rootSaga.d.ts +1 -1
- package/dist/core/src/redux/rootSaga.d.ts.map +1 -1
- package/dist/core/src/redux/toolkit/configureStore.d.ts +77 -0
- package/dist/core/src/redux/toolkit/configureStore.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/createAction.d.ts +180 -0
- package/dist/core/src/redux/toolkit/createAction.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/createReducer.d.ts +42 -0
- package/dist/core/src/redux/toolkit/createReducer.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/createSlice.d.ts +142 -0
- package/dist/core/src/redux/toolkit/createSlice.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/devtoolsExtension.d.ts +185 -0
- package/dist/core/src/redux/toolkit/devtoolsExtension.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/getDefaultMiddleware.d.ts +12 -0
- package/dist/core/src/redux/toolkit/getDefaultMiddleware.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/index.d.ts +13 -0
- package/dist/core/src/redux/toolkit/index.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/isPlainObject.d.ts +12 -0
- package/dist/core/src/redux/toolkit/isPlainObject.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/mapBuilders.d.ts +38 -0
- package/dist/core/src/redux/toolkit/mapBuilders.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/tsHelpers.d.ts +51 -0
- package/dist/core/src/redux/toolkit/tsHelpers.d.ts.map +1 -0
- package/dist/core/src/redux/toolkit/utils.d.ts +11 -0
- package/dist/core/src/redux/toolkit/utils.d.ts.map +1 -0
- package/dist/core/src/redux/utils/createDestroyableSlice.d.ts +3 -2
- package/dist/core/src/redux/utils/createDestroyableSlice.d.ts.map +1 -1
- package/dist/core/src/testUtils.d.ts +6 -25
- package/dist/core/src/testUtils.d.ts.map +1 -1
- package/dist/core/src/types/chat.d.ts +94 -18
- package/dist/core/src/types/chat.d.ts.map +1 -1
- package/dist/core/src/types/index.d.ts +2 -0
- package/dist/core/src/types/index.d.ts.map +1 -1
- package/dist/core/src/types/utils.d.ts +15 -4
- package/dist/core/src/types/utils.d.ts.map +1 -1
- package/dist/core/src/types/videoRoomSession.d.ts +4 -1
- package/dist/core/src/types/videoRoomSession.d.ts.map +1 -1
- package/dist/core/src/utils/eventTransformUtils.d.ts.map +1 -1
- package/dist/core/src/utils/index.d.ts +4 -1
- package/dist/core/src/utils/index.d.ts.map +1 -1
- package/dist/core/src/utils/proxyUtils.d.ts +10 -0
- package/dist/core/src/utils/proxyUtils.d.ts.map +1 -0
- package/dist/index.esm.js +14 -14
- package/dist/index.esm.js.map +3 -3
- package/dist/index.js +44 -41
- package/dist/index.js.map +3 -3
- package/dist/index.umd.js +3 -3
- package/dist/index.umd.js.map +1 -1
- package/dist/js/src/Client.d.ts +2 -2
- 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.docs.d.ts +5 -0
- package/dist/js/src/RoomSession.docs.d.ts.map +1 -1
- package/dist/js/src/RoomSessionDevice.docs.d.ts +2 -0
- package/dist/js/src/RoomSessionDevice.docs.d.ts.map +1 -1
- package/dist/js/src/RoomSessionScreenShare.docs.d.ts +2 -0
- package/dist/js/src/RoomSessionScreenShare.docs.d.ts.map +1 -1
- package/dist/js/src/chat/Client.d.ts +16 -0
- package/dist/js/src/chat/Client.d.ts.map +1 -0
- package/dist/js/src/chat/index.d.ts +2 -0
- package/dist/js/src/chat/index.d.ts.map +1 -0
- package/dist/js/src/createClient.d.ts +1 -21
- package/dist/js/src/createClient.d.ts.map +1 -1
- package/dist/js/src/features/actions.d.ts +1 -1
- package/dist/js/src/features/actions.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/testUtils.d.ts +8 -48
- package/dist/js/src/testUtils.d.ts.map +1 -1
- package/dist/js/tsconfig.build.tsbuildinfo +1 -1
- package/dist/webrtc/src/BaseConnection.d.ts +3 -0
- package/dist/webrtc/src/BaseConnection.d.ts.map +1 -1
- package/dist/webrtc/src/RTCPeer.d.ts.map +1 -1
- package/dist/webrtc/src/utils/webrtcHelpers.native.d.ts +2 -2
- package/dist/webrtc/src/utils/webrtcHelpers.native.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/Client.ts +3 -3
- package/src/RoomSession.docs.ts +6 -0
- package/src/RoomSessionDevice.docs.ts +3 -0
- package/src/RoomSessionScreenShare.docs.ts +3 -0
- package/src/chat/Client.test.ts +652 -0
- package/src/chat/{Chat.ts → Client.ts} +14 -14
- package/src/chat/index.ts +1 -0
- package/src/createClient.ts +1 -21
- package/src/index.ts +1 -1
- package/src/utils/constants.ts +1 -1
- package/dist/js/src/chat/Chat.d.ts +0 -16
- package/dist/js/src/chat/Chat.d.ts.map +0 -1
- package/src/chat/Chat.test.ts +0 -219
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
import WS from 'jest-websocket-mock'
|
|
2
|
+
import { Client } from './Client'
|
|
3
|
+
|
|
4
|
+
describe('ChatClient Object', () => {
|
|
5
|
+
const host = 'ws://localhost:1234'
|
|
6
|
+
const token = '<jwt>'
|
|
7
|
+
const messages = [
|
|
8
|
+
{
|
|
9
|
+
id: '5fdc8fc5-b7fe-4fbd-8204-f2310dec2614',
|
|
10
|
+
sender_id: '1507e5f9-075c-463d-94ba-a8f9ec0c7d4e',
|
|
11
|
+
content: 'hello world',
|
|
12
|
+
published_at: 1641393396.153,
|
|
13
|
+
},
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
let server: WS
|
|
17
|
+
beforeEach(async () => {
|
|
18
|
+
server = new WS(host)
|
|
19
|
+
server.on('connection', (socket) => {
|
|
20
|
+
socket.on('message', (data: any) => {
|
|
21
|
+
const parsedData = JSON.parse(data)
|
|
22
|
+
|
|
23
|
+
// The error message is not important for the test.
|
|
24
|
+
// The idea is just to document what's the expected
|
|
25
|
+
// behavior (reject) or not (resolve).
|
|
26
|
+
if (
|
|
27
|
+
parsedData.method === 'chat.unsubscribe' &&
|
|
28
|
+
(parsedData.params.channels.length === 0 ||
|
|
29
|
+
parsedData.params.channels.some((ch: any) =>
|
|
30
|
+
ch.name.endsWith('_error')
|
|
31
|
+
))
|
|
32
|
+
) {
|
|
33
|
+
socket.send(
|
|
34
|
+
JSON.stringify({
|
|
35
|
+
jsonrpc: '2.0',
|
|
36
|
+
id: parsedData.id,
|
|
37
|
+
error: { code: -32600, message: 'Invalid Request' },
|
|
38
|
+
})
|
|
39
|
+
)
|
|
40
|
+
} else if (parsedData.method === 'chat.messages.get') {
|
|
41
|
+
socket.send(
|
|
42
|
+
JSON.stringify({
|
|
43
|
+
jsonrpc: '2.0',
|
|
44
|
+
id: parsedData.id,
|
|
45
|
+
result: {
|
|
46
|
+
code: '200',
|
|
47
|
+
message: 'OK',
|
|
48
|
+
messages,
|
|
49
|
+
cursor: {
|
|
50
|
+
before: 'before',
|
|
51
|
+
after: 'after',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
)
|
|
56
|
+
} else if (parsedData.method === 'chat.members.get') {
|
|
57
|
+
socket.send(
|
|
58
|
+
JSON.stringify({
|
|
59
|
+
jsonrpc: '2.0',
|
|
60
|
+
id: parsedData.id,
|
|
61
|
+
result: {
|
|
62
|
+
code: '200',
|
|
63
|
+
message: 'Success',
|
|
64
|
+
members: [
|
|
65
|
+
{
|
|
66
|
+
id: '1507e5f9-075c-463d-94ba-a8f9ec0c7d4e',
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
)
|
|
72
|
+
} else if (parsedData.method === 'chat.member.set_state') {
|
|
73
|
+
socket.send(
|
|
74
|
+
JSON.stringify({
|
|
75
|
+
jsonrpc: '2.0',
|
|
76
|
+
id: parsedData.id,
|
|
77
|
+
result: {
|
|
78
|
+
code: '200',
|
|
79
|
+
message: 'Success',
|
|
80
|
+
},
|
|
81
|
+
})
|
|
82
|
+
)
|
|
83
|
+
} else if (parsedData.method === 'chat.member.get_state') {
|
|
84
|
+
socket.send(
|
|
85
|
+
JSON.stringify({
|
|
86
|
+
jsonrpc: '2.0',
|
|
87
|
+
id: parsedData.id,
|
|
88
|
+
result: {
|
|
89
|
+
code: '200',
|
|
90
|
+
message: 'Success',
|
|
91
|
+
channels: {
|
|
92
|
+
lobby: {
|
|
93
|
+
state: {
|
|
94
|
+
typing: true,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
member: {
|
|
99
|
+
id: '1507e5f9-075c-463d-94ba-a8f9ec0c7d4e',
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
})
|
|
103
|
+
)
|
|
104
|
+
} else {
|
|
105
|
+
socket.send(
|
|
106
|
+
JSON.stringify({
|
|
107
|
+
jsonrpc: '2.0',
|
|
108
|
+
id: parsedData.id,
|
|
109
|
+
result: {},
|
|
110
|
+
})
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
afterEach(() => {
|
|
118
|
+
WS.clean()
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('should automatically connect when calling either .subscribe() or .publish()', async () => {
|
|
122
|
+
const chat = new Client({
|
|
123
|
+
host,
|
|
124
|
+
token,
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
chat.on('message', () => {})
|
|
128
|
+
await chat.subscribe(['test'])
|
|
129
|
+
await chat.publish({
|
|
130
|
+
channel: 'test',
|
|
131
|
+
message: 'test',
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
const connectMsg = JSON.parse(server.messages[0].toString())
|
|
135
|
+
expect(connectMsg.method).toBe('signalwire.connect')
|
|
136
|
+
expect(server.messages.length).toBe(3)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it('should emit a single "signalwire.connect" at most when subscribing/publishing at the same time', async () => {
|
|
140
|
+
const chat = new Client({
|
|
141
|
+
host,
|
|
142
|
+
token,
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
chat.on('message', () => {})
|
|
146
|
+
await Promise.all([
|
|
147
|
+
chat.subscribe(['test']),
|
|
148
|
+
chat.publish({
|
|
149
|
+
channel: 'test',
|
|
150
|
+
message: 'test',
|
|
151
|
+
}),
|
|
152
|
+
])
|
|
153
|
+
|
|
154
|
+
const connectMsg = JSON.parse(server.messages[0].toString())
|
|
155
|
+
expect(connectMsg.method).toBe('signalwire.connect')
|
|
156
|
+
expect(
|
|
157
|
+
server.messages.filter((message) => {
|
|
158
|
+
const parsedMessage = JSON.parse(message.toString())
|
|
159
|
+
|
|
160
|
+
return parsedMessage.method === 'signalwire.connect'
|
|
161
|
+
}).length
|
|
162
|
+
).toBe(1)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
describe('message handler', () => {
|
|
166
|
+
it('should return a ChatMessage object', (done) => {
|
|
167
|
+
WS.clean()
|
|
168
|
+
server = new WS(host)
|
|
169
|
+
server.on('connection', (socket) => {
|
|
170
|
+
socket.on('message', (data: any) => {
|
|
171
|
+
const parsedData = JSON.parse(data)
|
|
172
|
+
socket.send(
|
|
173
|
+
JSON.stringify({
|
|
174
|
+
jsonrpc: '2.0',
|
|
175
|
+
id: parsedData.id,
|
|
176
|
+
result: {},
|
|
177
|
+
})
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
if (parsedData.method === 'chat.subscribe') {
|
|
181
|
+
socket.send(
|
|
182
|
+
JSON.stringify({
|
|
183
|
+
jsonrpc: '2.0',
|
|
184
|
+
id: '7a5cbfac-d1f8-4e7f-b1cf-9e1f7cdc6b54',
|
|
185
|
+
method: 'signalwire.event',
|
|
186
|
+
params: {
|
|
187
|
+
event_type: 'chat.channel.message',
|
|
188
|
+
event_channel: 'chat',
|
|
189
|
+
params: {
|
|
190
|
+
channel: 'lobby',
|
|
191
|
+
message: {
|
|
192
|
+
id: 'f5511ad5-4dc2-4d28-a449-cc39909093b9',
|
|
193
|
+
member: {
|
|
194
|
+
id: '1507e5f9-075c-463d-94ba-a8f9ec0c7d4e',
|
|
195
|
+
channel: 'lobby',
|
|
196
|
+
state: { active: true },
|
|
197
|
+
},
|
|
198
|
+
content: 'Hello World!',
|
|
199
|
+
published_at: 1641405257.795,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
timestamp: 1641405258.253,
|
|
203
|
+
},
|
|
204
|
+
})
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
})
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
const chat = new Client({
|
|
211
|
+
host,
|
|
212
|
+
token,
|
|
213
|
+
})
|
|
214
|
+
chat.on('message', (message) => {
|
|
215
|
+
expect(message.channel).toBe('lobby')
|
|
216
|
+
expect(message.id).toBe('f5511ad5-4dc2-4d28-a449-cc39909093b9')
|
|
217
|
+
expect(message.member).toStrictEqual({
|
|
218
|
+
id: '1507e5f9-075c-463d-94ba-a8f9ec0c7d4e',
|
|
219
|
+
channel: 'lobby',
|
|
220
|
+
state: { active: true },
|
|
221
|
+
})
|
|
222
|
+
expect(message.content).toBe('Hello World!')
|
|
223
|
+
expect(message.publishedAt).toStrictEqual(
|
|
224
|
+
new Date(1641405257.795 * 1000)
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
done()
|
|
228
|
+
})
|
|
229
|
+
chat.subscribe(['test1'])
|
|
230
|
+
})
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
describe('member event handlers', () => {
|
|
234
|
+
const _setupMockWS = (eventPayload: any) => {
|
|
235
|
+
WS.clean()
|
|
236
|
+
server = new WS(host)
|
|
237
|
+
server.on('connection', (socket) => {
|
|
238
|
+
socket.on('message', (data: any) => {
|
|
239
|
+
const parsedData = JSON.parse(data)
|
|
240
|
+
socket.send(
|
|
241
|
+
JSON.stringify({
|
|
242
|
+
jsonrpc: '2.0',
|
|
243
|
+
id: parsedData.id,
|
|
244
|
+
result: {},
|
|
245
|
+
})
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
if (parsedData.method === 'chat.subscribe') {
|
|
249
|
+
socket.send(JSON.stringify(eventPayload))
|
|
250
|
+
}
|
|
251
|
+
})
|
|
252
|
+
})
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
it('should return a ChatMember object on member.joined', (done) => {
|
|
256
|
+
_setupMockWS({
|
|
257
|
+
jsonrpc: '2.0',
|
|
258
|
+
id: '45266133-cdfe-4e99-a257-1ea77572f1d9',
|
|
259
|
+
method: 'signalwire.event',
|
|
260
|
+
params: {
|
|
261
|
+
event_type: 'chat.member.joined',
|
|
262
|
+
event_channel: 'chat',
|
|
263
|
+
params: {
|
|
264
|
+
channel: 'lobby',
|
|
265
|
+
member: {
|
|
266
|
+
id: '1507e5f9-075c-463d-94ba-a8f9ec0c7d4e',
|
|
267
|
+
channel: 'lobby',
|
|
268
|
+
state: { init: 1 },
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
timestamp: 1641468229.28,
|
|
272
|
+
},
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
const chat = new Client({
|
|
276
|
+
host,
|
|
277
|
+
token,
|
|
278
|
+
})
|
|
279
|
+
chat.on('member.joined', (member) => {
|
|
280
|
+
expect(member.channel).toBe('lobby')
|
|
281
|
+
expect(member.id).toBe('1507e5f9-075c-463d-94ba-a8f9ec0c7d4e')
|
|
282
|
+
expect(member.state).toStrictEqual({ init: 1 })
|
|
283
|
+
|
|
284
|
+
done()
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
chat.subscribe(['test1'])
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
it('should return a ChatMember object on member.updated', (done) => {
|
|
291
|
+
_setupMockWS({
|
|
292
|
+
jsonrpc: '2.0',
|
|
293
|
+
id: 'f734e59a-dea2-4de2-8369-7f6df4bf3016',
|
|
294
|
+
method: 'signalwire.event',
|
|
295
|
+
params: {
|
|
296
|
+
event_type: 'chat.member.updated',
|
|
297
|
+
event_channel: 'chat',
|
|
298
|
+
params: {
|
|
299
|
+
channel: 'lobby',
|
|
300
|
+
member: {
|
|
301
|
+
id: '1507e5f9-075c-463d-94ba-a8f9ec0c7d4e',
|
|
302
|
+
channel: 'lobby',
|
|
303
|
+
state: {
|
|
304
|
+
typing: true,
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
timestamp: 1641468242.538,
|
|
309
|
+
},
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
const chat = new Client({
|
|
313
|
+
host,
|
|
314
|
+
token,
|
|
315
|
+
})
|
|
316
|
+
chat.on('member.updated', (member) => {
|
|
317
|
+
expect(member.channel).toBe('lobby')
|
|
318
|
+
expect(member.id).toBe('1507e5f9-075c-463d-94ba-a8f9ec0c7d4e')
|
|
319
|
+
expect(member.state).toStrictEqual({
|
|
320
|
+
typing: true,
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
done()
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
chat.subscribe(['test1'])
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
it('should return a ChatMember object on member.left', (done) => {
|
|
330
|
+
_setupMockWS({
|
|
331
|
+
jsonrpc: '2.0',
|
|
332
|
+
id: '45266133-cdfe-4e99-a257-1ea77572f1d9',
|
|
333
|
+
method: 'signalwire.event',
|
|
334
|
+
params: {
|
|
335
|
+
event_type: 'chat.member.left',
|
|
336
|
+
event_channel: 'chat',
|
|
337
|
+
params: {
|
|
338
|
+
channel: 'lobby',
|
|
339
|
+
member: {
|
|
340
|
+
id: '1507e5f9-075c-463d-94ba-a8f9ec0c7d4e',
|
|
341
|
+
channel: 'lobby',
|
|
342
|
+
state: {},
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
timestamp: 1641468229.28,
|
|
346
|
+
},
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
const chat = new Client({
|
|
350
|
+
host,
|
|
351
|
+
token,
|
|
352
|
+
})
|
|
353
|
+
chat.on('member.left', (member) => {
|
|
354
|
+
expect(member.channel).toBe('lobby')
|
|
355
|
+
expect(member.id).toBe('1507e5f9-075c-463d-94ba-a8f9ec0c7d4e')
|
|
356
|
+
expect(member.state).toStrictEqual({})
|
|
357
|
+
|
|
358
|
+
done()
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
chat.subscribe(['test1'])
|
|
362
|
+
})
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
describe('Subscribe', () => {
|
|
366
|
+
it('should convert channels into the internal channel notation when calling .subscribe()', async () => {
|
|
367
|
+
const chat = new Client({
|
|
368
|
+
host,
|
|
369
|
+
token,
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
chat.on('message', () => {})
|
|
373
|
+
await chat.subscribe(['test1', 'test2', 'test3'])
|
|
374
|
+
|
|
375
|
+
const subscribeMsg = JSON.parse(server.messages[1].toString())
|
|
376
|
+
expect(subscribeMsg.params.channels).toStrictEqual([
|
|
377
|
+
{ name: 'test1' },
|
|
378
|
+
{ name: 'test2' },
|
|
379
|
+
{ name: 'test3' },
|
|
380
|
+
])
|
|
381
|
+
})
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
describe('Publish', () => {
|
|
385
|
+
it('should support publishing-only mode', async () => {
|
|
386
|
+
const chat = new Client({
|
|
387
|
+
host,
|
|
388
|
+
token,
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
const params = {
|
|
392
|
+
channel: 'test',
|
|
393
|
+
message: 'test',
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
await chat.publish(params)
|
|
397
|
+
|
|
398
|
+
server.messages.forEach((message, i) => {
|
|
399
|
+
const parsedMessage = JSON.parse(message.toString())
|
|
400
|
+
|
|
401
|
+
if (i === 0) {
|
|
402
|
+
expect(parsedMessage.method).toBe('signalwire.connect')
|
|
403
|
+
} else {
|
|
404
|
+
expect(parsedMessage.method).toBe('chat.publish')
|
|
405
|
+
expect(parsedMessage.params).toStrictEqual(params)
|
|
406
|
+
}
|
|
407
|
+
})
|
|
408
|
+
})
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
describe('Unsubscribe', () => {
|
|
412
|
+
it('should convert channels into the internal channel notation', async () => {
|
|
413
|
+
const chat = new Client({
|
|
414
|
+
host,
|
|
415
|
+
token,
|
|
416
|
+
})
|
|
417
|
+
|
|
418
|
+
chat.on('message', () => {})
|
|
419
|
+
await chat.subscribe(['test1', 'test2', 'test3'])
|
|
420
|
+
await chat.unsubscribe(['test1', 'test2', 'test3'])
|
|
421
|
+
|
|
422
|
+
const unsubscribeMsg = JSON.parse(server.messages[1].toString())
|
|
423
|
+
expect(unsubscribeMsg.params.channels).toStrictEqual([
|
|
424
|
+
{ name: 'test1' },
|
|
425
|
+
{ name: 'test2' },
|
|
426
|
+
{ name: 'test3' },
|
|
427
|
+
])
|
|
428
|
+
})
|
|
429
|
+
|
|
430
|
+
it('should allow the user to .unsubscribe() from any subgroup of subscribed channels', async () => {
|
|
431
|
+
expect.assertions(4)
|
|
432
|
+
const chat = new Client({
|
|
433
|
+
host,
|
|
434
|
+
token,
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
chat.on('message', () => {})
|
|
438
|
+
|
|
439
|
+
await chat.subscribe(['test1', 'test2', 'test3'])
|
|
440
|
+
expect(await chat.unsubscribe(['test1', 'test3'])).toBeUndefined()
|
|
441
|
+
expect(await chat.unsubscribe(['test1', 'test2'])).toBeUndefined()
|
|
442
|
+
expect(await chat.unsubscribe(['test2', 'test3'])).toBeUndefined()
|
|
443
|
+
expect(
|
|
444
|
+
await chat.unsubscribe(['test1', 'test2', 'test3'])
|
|
445
|
+
).toBeUndefined()
|
|
446
|
+
})
|
|
447
|
+
|
|
448
|
+
it('should reject if its called before the session is authorized', async () => {
|
|
449
|
+
expect.assertions(1)
|
|
450
|
+
const chat = new Client({
|
|
451
|
+
host,
|
|
452
|
+
token,
|
|
453
|
+
})
|
|
454
|
+
|
|
455
|
+
chat.on('message', () => {})
|
|
456
|
+
|
|
457
|
+
try {
|
|
458
|
+
await chat.unsubscribe(['test1'])
|
|
459
|
+
} catch (err) {
|
|
460
|
+
expect(err.message).toBe(
|
|
461
|
+
'You must be authenticated to unsubscribe from a channel'
|
|
462
|
+
)
|
|
463
|
+
}
|
|
464
|
+
})
|
|
465
|
+
|
|
466
|
+
it("should reject if it's called without channels", async () => {
|
|
467
|
+
expect.assertions(1)
|
|
468
|
+
const chat = new Client({
|
|
469
|
+
host,
|
|
470
|
+
token,
|
|
471
|
+
})
|
|
472
|
+
|
|
473
|
+
chat.on('message', () => {})
|
|
474
|
+
|
|
475
|
+
// This is to force the session to be connected when
|
|
476
|
+
// calling unsubscribe()
|
|
477
|
+
await chat.publish({
|
|
478
|
+
channel: 'test',
|
|
479
|
+
message: 'test',
|
|
480
|
+
})
|
|
481
|
+
|
|
482
|
+
await expect(() => chat.unsubscribe(['test1_error'])).rejects.toBeTruthy()
|
|
483
|
+
})
|
|
484
|
+
|
|
485
|
+
it('should reject if the user calls .unsubscribe() with channels different than the ones they are subscribed to', async () => {
|
|
486
|
+
expect.assertions(1)
|
|
487
|
+
const chat = new Client({
|
|
488
|
+
host,
|
|
489
|
+
token,
|
|
490
|
+
})
|
|
491
|
+
|
|
492
|
+
chat.on('message', () => {})
|
|
493
|
+
|
|
494
|
+
await chat.subscribe(['test1', 'test2', 'test3', 'test4'])
|
|
495
|
+
await expect(() =>
|
|
496
|
+
chat.unsubscribe(['test1', 'test5_error'])
|
|
497
|
+
).rejects.toBeTruthy()
|
|
498
|
+
})
|
|
499
|
+
})
|
|
500
|
+
|
|
501
|
+
describe('getMembers', () => {
|
|
502
|
+
it('should send the proper RPC and format the response', async () => {
|
|
503
|
+
const chat = new Client({
|
|
504
|
+
host,
|
|
505
|
+
token,
|
|
506
|
+
})
|
|
507
|
+
chat.on('message', () => {})
|
|
508
|
+
await chat.subscribe(['test1'])
|
|
509
|
+
|
|
510
|
+
const response = await chat.getMembers({ channel: 'test1' })
|
|
511
|
+
|
|
512
|
+
const request = JSON.parse(server.messages[2].toString())
|
|
513
|
+
expect(request.method).toEqual('chat.members.get')
|
|
514
|
+
expect(request.params).toStrictEqual({ channel: 'test1' })
|
|
515
|
+
|
|
516
|
+
expect(response).toStrictEqual({
|
|
517
|
+
members: [
|
|
518
|
+
{
|
|
519
|
+
id: '1507e5f9-075c-463d-94ba-a8f9ec0c7d4e',
|
|
520
|
+
},
|
|
521
|
+
],
|
|
522
|
+
})
|
|
523
|
+
})
|
|
524
|
+
})
|
|
525
|
+
|
|
526
|
+
describe('getMessages', () => {
|
|
527
|
+
it('should send the proper RPC and format the response', async () => {
|
|
528
|
+
const chat = new Client({
|
|
529
|
+
host,
|
|
530
|
+
token,
|
|
531
|
+
})
|
|
532
|
+
chat.on('message', () => {})
|
|
533
|
+
await chat.subscribe(['test1'])
|
|
534
|
+
|
|
535
|
+
const response = await chat.getMessages({
|
|
536
|
+
channel: 'test1',
|
|
537
|
+
cursor: { before: 'before' },
|
|
538
|
+
})
|
|
539
|
+
|
|
540
|
+
const request = JSON.parse(server.messages[2].toString())
|
|
541
|
+
expect(request.method).toEqual('chat.messages.get')
|
|
542
|
+
expect(request.params).toStrictEqual({
|
|
543
|
+
channel: 'test1',
|
|
544
|
+
cursor: { before: 'before' },
|
|
545
|
+
})
|
|
546
|
+
|
|
547
|
+
expect(response).toStrictEqual({
|
|
548
|
+
messages: [
|
|
549
|
+
{
|
|
550
|
+
id: '5fdc8fc5-b7fe-4fbd-8204-f2310dec2614',
|
|
551
|
+
senderId: '1507e5f9-075c-463d-94ba-a8f9ec0c7d4e',
|
|
552
|
+
content: 'hello world',
|
|
553
|
+
publishedAt: new Date(1641393396.153 * 1000),
|
|
554
|
+
},
|
|
555
|
+
],
|
|
556
|
+
cursor: {
|
|
557
|
+
before: 'before',
|
|
558
|
+
after: 'after',
|
|
559
|
+
},
|
|
560
|
+
})
|
|
561
|
+
})
|
|
562
|
+
})
|
|
563
|
+
|
|
564
|
+
describe('setState', () => {
|
|
565
|
+
it('should send the proper RPC and format the response', async () => {
|
|
566
|
+
const chat = new Client({
|
|
567
|
+
host,
|
|
568
|
+
token,
|
|
569
|
+
})
|
|
570
|
+
chat.on('message', () => {})
|
|
571
|
+
await chat.subscribe(['test1'])
|
|
572
|
+
|
|
573
|
+
const response = await chat.setMemberState({
|
|
574
|
+
memberId: 'memberUuid1',
|
|
575
|
+
channels: 'test1',
|
|
576
|
+
state: { typing: true },
|
|
577
|
+
})
|
|
578
|
+
|
|
579
|
+
const request = JSON.parse(server.messages[2].toString())
|
|
580
|
+
expect(request.method).toEqual('chat.member.set_state')
|
|
581
|
+
expect(request.params).toStrictEqual({
|
|
582
|
+
member_id: 'memberUuid1',
|
|
583
|
+
channels: [{ name: 'test1' }],
|
|
584
|
+
state: { typing: true },
|
|
585
|
+
})
|
|
586
|
+
|
|
587
|
+
expect(response).toStrictEqual(undefined)
|
|
588
|
+
})
|
|
589
|
+
})
|
|
590
|
+
|
|
591
|
+
describe('getState', () => {
|
|
592
|
+
it('should send the proper RPC and format the response', async () => {
|
|
593
|
+
const chat = new Client({
|
|
594
|
+
host,
|
|
595
|
+
token,
|
|
596
|
+
})
|
|
597
|
+
chat.on('message', () => {})
|
|
598
|
+
await chat.subscribe(['test1'])
|
|
599
|
+
|
|
600
|
+
const response = await chat.getMemberState({
|
|
601
|
+
memberId: 'memberId',
|
|
602
|
+
channels: 'test1',
|
|
603
|
+
})
|
|
604
|
+
|
|
605
|
+
const request = JSON.parse(server.messages[2].toString())
|
|
606
|
+
expect(request.method).toEqual('chat.member.get_state')
|
|
607
|
+
expect(request.params).toStrictEqual({
|
|
608
|
+
channels: [{ name: 'test1' }],
|
|
609
|
+
member_id: 'memberId',
|
|
610
|
+
})
|
|
611
|
+
|
|
612
|
+
expect(response).toStrictEqual({
|
|
613
|
+
channels: {
|
|
614
|
+
lobby: {
|
|
615
|
+
state: {
|
|
616
|
+
typing: true,
|
|
617
|
+
},
|
|
618
|
+
},
|
|
619
|
+
},
|
|
620
|
+
})
|
|
621
|
+
})
|
|
622
|
+
|
|
623
|
+
it('should send the proper RPC without (optional) channels', async () => {
|
|
624
|
+
const chat = new Client({
|
|
625
|
+
host,
|
|
626
|
+
token,
|
|
627
|
+
})
|
|
628
|
+
chat.on('message', () => {})
|
|
629
|
+
await chat.subscribe(['test1'])
|
|
630
|
+
|
|
631
|
+
const response = await chat.getMemberState({
|
|
632
|
+
memberId: 'memberId',
|
|
633
|
+
})
|
|
634
|
+
|
|
635
|
+
const request = JSON.parse(server.messages[2].toString())
|
|
636
|
+
expect(request.method).toEqual('chat.member.get_state')
|
|
637
|
+
expect(request.params).toStrictEqual({
|
|
638
|
+
member_id: 'memberId',
|
|
639
|
+
})
|
|
640
|
+
|
|
641
|
+
expect(response).toStrictEqual({
|
|
642
|
+
channels: {
|
|
643
|
+
lobby: {
|
|
644
|
+
state: {
|
|
645
|
+
typing: true,
|
|
646
|
+
},
|
|
647
|
+
},
|
|
648
|
+
},
|
|
649
|
+
})
|
|
650
|
+
})
|
|
651
|
+
})
|
|
652
|
+
})
|
|
@@ -8,40 +8,40 @@ import type {
|
|
|
8
8
|
import { getLogger } from '@signalwire/core'
|
|
9
9
|
import { createClient } from '../createClient'
|
|
10
10
|
|
|
11
|
-
export interface
|
|
11
|
+
export interface ClientApiEvents extends ChatNamespace.BaseChatApiEvents {}
|
|
12
12
|
|
|
13
|
-
export interface
|
|
14
|
-
interface
|
|
13
|
+
export interface ClientFullState extends Client {}
|
|
14
|
+
interface ClientMain
|
|
15
15
|
extends ChatContract,
|
|
16
|
-
Omit<ConsumerContract<
|
|
16
|
+
Omit<ConsumerContract<ClientApiEvents, ClientFullState>, 'subscribe'> {}
|
|
17
17
|
|
|
18
|
-
interface
|
|
18
|
+
interface ClientDocs extends ClientMain {}
|
|
19
19
|
|
|
20
|
-
export interface
|
|
20
|
+
export interface Client extends AssertSameType<ClientMain, ClientDocs> {}
|
|
21
21
|
|
|
22
|
-
export interface
|
|
22
|
+
export interface ClientOptions extends UserOptions {}
|
|
23
23
|
|
|
24
|
-
export const
|
|
24
|
+
export const Client = function (chatOptions: ClientOptions) {
|
|
25
25
|
if ('production' === process.env.NODE_ENV) {
|
|
26
26
|
getLogger().warn(
|
|
27
27
|
'`Chat` is still under development and may change in the future without prior notice.'
|
|
28
28
|
)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const client = createClient<
|
|
32
|
-
const subscribe:
|
|
31
|
+
const client = createClient<Client>(chatOptions)
|
|
32
|
+
const subscribe: Client['subscribe'] = async (channels) => {
|
|
33
33
|
await client.connect()
|
|
34
34
|
|
|
35
35
|
return client.chat.subscribe(channels)
|
|
36
36
|
}
|
|
37
|
-
const publish:
|
|
37
|
+
const publish: Client['publish'] = async (params) => {
|
|
38
38
|
await client.connect()
|
|
39
39
|
|
|
40
40
|
return client.chat.publish(params)
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
return new Proxy<
|
|
44
|
-
get(target:
|
|
43
|
+
return new Proxy<Client>(client.chat, {
|
|
44
|
+
get(target: Client, prop: keyof Client, receiver: any) {
|
|
45
45
|
if (prop === 'subscribe') {
|
|
46
46
|
return subscribe
|
|
47
47
|
} else if (prop === 'publish') {
|
|
@@ -52,4 +52,4 @@ export const Chat = function (chatOptions: ChatOptions) {
|
|
|
52
52
|
},
|
|
53
53
|
})
|
|
54
54
|
// For consistency with other constructors we'll make TS force the use of `new`
|
|
55
|
-
} as unknown as { new (chatOptions:
|
|
55
|
+
} as unknown as { new (chatOptions: ClientOptions): Client }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Client'
|