@dxos/messaging 0.5.8 → 0.5.9-main.079a532
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/lib/browser/index.mjs +812 -559
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +778 -545
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/messenger-monitor.d.ts +8 -0
- package/dist/types/src/messenger-monitor.d.ts.map +1 -0
- package/dist/types/src/messenger.d.ts +1 -0
- package/dist/types/src/messenger.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-client-monitor.d.ts +30 -0
- package/dist/types/src/signal-client/signal-client-monitor.d.ts.map +1 -0
- package/dist/types/src/signal-client/signal-client.d.ts +25 -50
- package/dist/types/src/signal-client/signal-client.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-local-state.d.ts +46 -0
- package/dist/types/src/signal-client/signal-local-state.d.ts.map +1 -0
- package/dist/types/src/signal-client/signal-rpc-client-monitor.d.ts +6 -0
- package/dist/types/src/signal-client/signal-rpc-client-monitor.d.ts.map +1 -0
- package/dist/types/src/signal-client/signal-rpc-client.d.ts +4 -2
- package/dist/types/src/signal-client/signal-rpc-client.d.ts.map +1 -1
- package/dist/types/src/signal-manager/memory-signal-manager.d.ts +0 -2
- package/dist/types/src/signal-manager/memory-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-manager/signal-manager.d.ts +0 -2
- package/dist/types/src/signal-manager/signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-manager/websocket-signal-manager-monitor.d.ts +8 -0
- package/dist/types/src/signal-manager/websocket-signal-manager-monitor.d.ts.map +1 -0
- package/dist/types/src/signal-manager/websocket-signal-manager.d.ts +7 -3
- package/dist/types/src/signal-manager/websocket-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-methods.d.ts +6 -4
- package/dist/types/src/signal-methods.d.ts.map +1 -1
- package/package.json +13 -12
- package/src/messenger-monitor.ts +20 -0
- package/src/messenger.ts +16 -5
- package/src/signal-client/signal-client-monitor.ts +111 -0
- package/src/signal-client/signal-client.test.ts +111 -259
- package/src/signal-client/signal-client.ts +141 -252
- package/src/signal-client/signal-local-state.ts +156 -0
- package/src/signal-client/signal-rpc-client-monitor.ts +15 -0
- package/src/signal-client/signal-rpc-client.ts +38 -21
- package/src/signal-manager/memory-signal-manager.ts +0 -2
- package/src/signal-manager/signal-manager.ts +0 -3
- package/src/signal-manager/websocket-signal-manager-monitor.ts +20 -0
- package/src/signal-manager/websocket-signal-manager.ts +48 -26
- package/src/signal-methods.ts +7 -4
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
// Copyright 2020 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
6
|
+
import { expect } from 'earljs';
|
|
6
7
|
|
|
7
|
-
import {
|
|
8
|
-
import { type
|
|
8
|
+
import { Trigger, asyncTimeout, waitForCondition } from '@dxos/async';
|
|
9
|
+
import { type TaggedType } from '@dxos/codec-protobuf';
|
|
9
10
|
import { PublicKey } from '@dxos/keys';
|
|
10
11
|
import { type TYPES } from '@dxos/protocols';
|
|
11
12
|
import { runTestSignalServer, type SignalServerRunner } from '@dxos/signal';
|
|
12
13
|
import { afterAll, beforeAll, describe, test, afterTest } from '@dxos/test';
|
|
14
|
+
import { ComplexSet, range } from '@dxos/util';
|
|
13
15
|
|
|
14
16
|
import { SignalClient } from './signal-client';
|
|
15
17
|
|
|
@@ -22,307 +24,157 @@ const PAYLOAD: TaggedType<TYPES, 'google.protobuf.Any'> = {
|
|
|
22
24
|
describe('SignalClient', () => {
|
|
23
25
|
let broker1: SignalServerRunner;
|
|
24
26
|
|
|
25
|
-
let broker2: SignalServerRunner;
|
|
26
|
-
|
|
27
27
|
beforeAll(async () => {
|
|
28
28
|
broker1 = await runTestSignalServer();
|
|
29
|
-
// broker2 = await await createTestBroker(signalApiPort2);
|
|
30
29
|
});
|
|
31
30
|
|
|
32
|
-
afterAll(() => {
|
|
33
|
-
|
|
34
|
-
// code await broker2.stop();
|
|
31
|
+
afterAll(async () => {
|
|
32
|
+
await broker1.stop();
|
|
35
33
|
});
|
|
36
34
|
|
|
37
|
-
const waitForSubscription = async (signal: SignalClient, peerId: PublicKey) => {
|
|
38
|
-
await asyncTimeout(
|
|
39
|
-
signal._reconciled.waitForCondition(() => signal._messageStreams.has(peerId)),
|
|
40
|
-
500,
|
|
41
|
-
);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
35
|
test('message between 2 clients', async () => {
|
|
45
|
-
const peer1 =
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
);
|
|
55
|
-
void api1.open();
|
|
56
|
-
afterTest(() => api1.close());
|
|
57
|
-
const api2 = new SignalClient(broker1.url(), (async () => {}) as any, async () => {});
|
|
58
|
-
void api2.open();
|
|
59
|
-
afterTest(() => api2.close());
|
|
60
|
-
|
|
61
|
-
await api1.subscribeMessages(peer1);
|
|
62
|
-
await waitForSubscription(api1, peer1);
|
|
63
|
-
|
|
64
|
-
const message = {
|
|
65
|
-
author: peer2,
|
|
66
|
-
recipient: peer1,
|
|
67
|
-
payload: PAYLOAD,
|
|
68
|
-
};
|
|
69
|
-
await api2.sendMessage(message);
|
|
70
|
-
expect(await received.wait()).toEqual(message);
|
|
71
|
-
})
|
|
72
|
-
.timeout(500)
|
|
73
|
-
.retries(2);
|
|
36
|
+
const [peer1, peer2] = setupPeers({ peerCount: 2 });
|
|
37
|
+
|
|
38
|
+
await peer1.client.subscribeMessages(peer1.id);
|
|
39
|
+
await waitForSubscription(peer1.client, peer1.id);
|
|
40
|
+
|
|
41
|
+
const message = createMessage(peer2, peer1);
|
|
42
|
+
await peer2.client.sendMessage(message);
|
|
43
|
+
expect(await peer1.waitForNextMessage()).toEqual(message);
|
|
44
|
+
}).timeout(500);
|
|
74
45
|
|
|
75
46
|
test('join', async () => {
|
|
76
47
|
const topic = PublicKey.random();
|
|
77
|
-
const peer1 =
|
|
78
|
-
const peer2 = PublicKey.random();
|
|
79
|
-
|
|
80
|
-
const trigger1 = new Trigger();
|
|
81
|
-
const api1 = new SignalClient(
|
|
82
|
-
broker1.url(),
|
|
83
|
-
async () => {},
|
|
84
|
-
async ({ swarmEvent }) => {
|
|
85
|
-
if (!!swarmEvent.peerAvailable && peer2.equals(swarmEvent.peerAvailable.peer)) {
|
|
86
|
-
trigger1.wake();
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
);
|
|
90
|
-
void api1.open();
|
|
91
|
-
afterTest(() => api1.close());
|
|
92
|
-
|
|
93
|
-
const trigger2 = new Trigger();
|
|
94
|
-
const api2 = new SignalClient(
|
|
95
|
-
broker1.url(),
|
|
96
|
-
async () => {},
|
|
97
|
-
async ({ swarmEvent }) => {
|
|
98
|
-
if (!!swarmEvent.peerAvailable && peer1.equals(swarmEvent.peerAvailable.peer)) {
|
|
99
|
-
trigger2.wake();
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
);
|
|
103
|
-
void api2.open();
|
|
104
|
-
afterTest(() => api2.close());
|
|
105
|
-
await api1.join({ topic, peerId: peer1 });
|
|
106
|
-
await api2.join({ topic, peerId: peer2 });
|
|
48
|
+
const [peer1, peer2] = setupPeers({ peerCount: 2 });
|
|
107
49
|
|
|
108
|
-
await
|
|
109
|
-
await
|
|
110
|
-
})
|
|
111
|
-
.timeout(500)
|
|
112
|
-
.retries(2);
|
|
50
|
+
await peer1.client.join({ topic, peerId: peer1.id });
|
|
51
|
+
await peer2.client.join({ topic, peerId: peer2.id });
|
|
113
52
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const received = new Trigger<any>();
|
|
118
|
-
const api1 = new SignalClient(
|
|
119
|
-
broker1.url(),
|
|
120
|
-
async (msg) => {
|
|
121
|
-
received.wake(msg);
|
|
122
|
-
},
|
|
123
|
-
async () => {},
|
|
124
|
-
);
|
|
125
|
-
void api1.open();
|
|
126
|
-
afterTest(() => api1.close());
|
|
53
|
+
await peer1.waitForPeer(peer2.id);
|
|
54
|
+
await peer2.waitForPeer(peer1.id);
|
|
55
|
+
}).timeout(500);
|
|
127
56
|
|
|
128
|
-
|
|
129
|
-
|
|
57
|
+
test('signal to self', async () => {
|
|
58
|
+
const [peer1, peer2] = setupPeers({ peerCount: 2 });
|
|
130
59
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
recipient: peer1,
|
|
134
|
-
payload: PAYLOAD,
|
|
135
|
-
};
|
|
136
|
-
await api1.sendMessage(message);
|
|
60
|
+
await peer1.client.subscribeMessages(peer1.id);
|
|
61
|
+
await waitForSubscription(peer1.client, peer1.id);
|
|
137
62
|
|
|
138
|
-
|
|
63
|
+
const message = createMessage(peer2, peer1);
|
|
64
|
+
await peer1.client.sendMessage(message);
|
|
65
|
+
expect(await peer1.waitForNextMessage()).toEqual(message);
|
|
139
66
|
}).timeout(500);
|
|
140
67
|
|
|
141
68
|
test('unsubscribe from messages', async () => {
|
|
142
|
-
const peer1 =
|
|
143
|
-
const peer2 = PublicKey.random();
|
|
144
|
-
|
|
145
|
-
const received = new Event<any>();
|
|
146
|
-
const client1 = new SignalClient(
|
|
147
|
-
broker1.url(),
|
|
148
|
-
async (msg) => {
|
|
149
|
-
received.emit(msg);
|
|
150
|
-
},
|
|
151
|
-
async () => {},
|
|
152
|
-
);
|
|
153
|
-
void client1.open();
|
|
154
|
-
afterTest(() => client1.close());
|
|
69
|
+
const [peer1, peer2] = setupPeers({ peerCount: 2 });
|
|
155
70
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
71
|
+
await peer1.client.subscribeMessages(peer1.id);
|
|
72
|
+
await peer2.client.subscribeMessages(peer2.id);
|
|
73
|
+
await waitForSubscription(peer1.client, peer1.id);
|
|
159
74
|
|
|
160
|
-
|
|
161
|
-
await client2.subscribeMessages(peer2);
|
|
162
|
-
await waitForSubscription(client2, peer2);
|
|
163
|
-
|
|
164
|
-
const message = {
|
|
165
|
-
author: peer2,
|
|
166
|
-
recipient: peer1,
|
|
167
|
-
payload: PAYLOAD,
|
|
168
|
-
};
|
|
75
|
+
const message = createMessage(peer2, peer1);
|
|
169
76
|
|
|
170
77
|
{
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return true;
|
|
174
|
-
});
|
|
175
|
-
await client2.sendMessage(message);
|
|
176
|
-
await promise;
|
|
78
|
+
await peer2.client.sendMessage(message);
|
|
79
|
+
expect(await peer1.waitForNextMessage()).toEqual(message);
|
|
177
80
|
}
|
|
178
81
|
|
|
179
82
|
// unsubscribing.
|
|
180
|
-
await
|
|
83
|
+
await peer1.client.unsubscribeMessages(peer1.id);
|
|
181
84
|
|
|
182
85
|
{
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
return true;
|
|
186
|
-
});
|
|
187
|
-
await client2.sendMessage(message);
|
|
188
|
-
await expect(asyncTimeout(promise, 200)).toBeRejected();
|
|
86
|
+
await peer2.client.sendMessage(message);
|
|
87
|
+
await expect(peer1.waitForNextMessage({ timeout: 200 })).toBeRejected();
|
|
189
88
|
}
|
|
190
|
-
})
|
|
191
|
-
.timeout(1_000)
|
|
192
|
-
.retries(2);
|
|
89
|
+
}).timeout(1_500);
|
|
193
90
|
|
|
194
91
|
test('signal after re-entrance', async () => {
|
|
195
|
-
const peer1 =
|
|
196
|
-
const peer2 = PublicKey.random();
|
|
197
|
-
|
|
198
|
-
const received = new Event<any>();
|
|
199
|
-
const client1 = new SignalClient(
|
|
200
|
-
broker1.url(),
|
|
201
|
-
async (msg) => {
|
|
202
|
-
received.emit(msg);
|
|
203
|
-
},
|
|
204
|
-
async () => {},
|
|
205
|
-
);
|
|
206
|
-
void client1.open();
|
|
207
|
-
afterTest(() => client1.close());
|
|
92
|
+
const [peer1, peer2] = setupPeers({ peerCount: 2 });
|
|
208
93
|
|
|
209
|
-
const
|
|
210
|
-
void client2.open();
|
|
211
|
-
afterTest(() => client2.close());
|
|
212
|
-
|
|
213
|
-
const message = {
|
|
214
|
-
author: peer2,
|
|
215
|
-
recipient: peer1,
|
|
216
|
-
payload: PAYLOAD,
|
|
217
|
-
};
|
|
94
|
+
const message = createMessage(peer2, peer1);
|
|
218
95
|
|
|
219
|
-
await
|
|
220
|
-
await waitForSubscription(
|
|
96
|
+
await peer1.client.subscribeMessages(peer1.id);
|
|
97
|
+
await waitForSubscription(peer1.client, peer1.id);
|
|
221
98
|
|
|
222
99
|
{
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
return true;
|
|
226
|
-
});
|
|
227
|
-
await client2.sendMessage(message);
|
|
228
|
-
await promise;
|
|
100
|
+
await peer2.client.sendMessage(message);
|
|
101
|
+
expect(await peer1.waitForNextMessage()).toEqual(message);
|
|
229
102
|
}
|
|
230
103
|
|
|
231
104
|
//
|
|
232
105
|
// close and reopen first client
|
|
233
106
|
//
|
|
234
107
|
|
|
235
|
-
await
|
|
236
|
-
|
|
237
|
-
await waitForSubscription(
|
|
108
|
+
await peer1.client.close();
|
|
109
|
+
await peer1.client.open();
|
|
110
|
+
await waitForSubscription(peer1.client, peer1.id);
|
|
238
111
|
|
|
239
112
|
{
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
return true;
|
|
243
|
-
});
|
|
244
|
-
await client2.sendMessage(message);
|
|
245
|
-
await promise;
|
|
113
|
+
await peer2.client.sendMessage(message);
|
|
114
|
+
expect(await peer1.waitForNextMessage()).toEqual(message);
|
|
246
115
|
}
|
|
247
|
-
})
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const
|
|
254
|
-
const
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
);
|
|
269
|
-
void api2.open();
|
|
270
|
-
afterTest(() => api2.close());
|
|
271
|
-
|
|
272
|
-
await api1.join({ topic, peerId: peer1 });
|
|
273
|
-
await api2.join({ topic, peerId: peer2 });
|
|
274
|
-
|
|
275
|
-
// await waitForExpect(async () => {
|
|
276
|
-
// const peers = await api2.lookup(topic);
|
|
277
|
-
// expect(peers.length).toEqual(2);
|
|
278
|
-
// }, 4_000);
|
|
279
|
-
|
|
280
|
-
// await waitForExpect(async () => {
|
|
281
|
-
// const peers = await api1.lookup(topic);
|
|
282
|
-
// expect(peers.length).toEqual(2);
|
|
283
|
-
// }, 4_000);
|
|
284
|
-
})
|
|
285
|
-
.timeout(5_000);
|
|
286
|
-
|
|
287
|
-
// Skip because communication between signal servers is not yet implemented.
|
|
288
|
-
test
|
|
289
|
-
.skip('newly joined peer can receive signals from other signal servers', async () => {
|
|
290
|
-
const topic = PublicKey.random();
|
|
291
|
-
const peer1 = PublicKey.random();
|
|
292
|
-
const peer2 = PublicKey.random();
|
|
293
|
-
const signalMock =
|
|
294
|
-
mockFn<
|
|
295
|
-
({ author, recipient, payload }: { author: PublicKey; recipient: PublicKey; payload: Any }) => Promise<void>
|
|
296
|
-
>().resolvesTo();
|
|
297
|
-
|
|
298
|
-
const api1 = new SignalClient(
|
|
299
|
-
broker1.url(),
|
|
300
|
-
async () => {},
|
|
301
|
-
async () => {},
|
|
116
|
+
}).timeout(1_000);
|
|
117
|
+
|
|
118
|
+
const setupPeers = (options?: { broker?: SignalServerRunner; peerCount?: number }): TestPeer[] => {
|
|
119
|
+
return range(options?.peerCount ?? 1, () => {
|
|
120
|
+
const peers = new ComplexSet(PublicKey.hash);
|
|
121
|
+
let nextMessage: any | null = null;
|
|
122
|
+
const nextMessageTrigger = new Trigger();
|
|
123
|
+
const id = PublicKey.random();
|
|
124
|
+
const client = new SignalClient(
|
|
125
|
+
(options?.broker ?? broker1).url(),
|
|
126
|
+
async (msg) => {
|
|
127
|
+
nextMessage = msg;
|
|
128
|
+
nextMessageTrigger.wake();
|
|
129
|
+
},
|
|
130
|
+
async (event) => {
|
|
131
|
+
if (event.swarmEvent.peerAvailable) {
|
|
132
|
+
peers.add(PublicKey.from(event.swarmEvent.peerAvailable.peer));
|
|
133
|
+
} else if (event.swarmEvent.peerLeft) {
|
|
134
|
+
peers.delete(PublicKey.from(event.swarmEvent.peerLeft.peer));
|
|
135
|
+
}
|
|
136
|
+
},
|
|
302
137
|
);
|
|
303
|
-
void
|
|
304
|
-
afterTest(() =>
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
value: Buffer.from('0'),
|
|
138
|
+
void client.open();
|
|
139
|
+
afterTest(async () => {
|
|
140
|
+
await client.close();
|
|
141
|
+
});
|
|
142
|
+
return {
|
|
143
|
+
id,
|
|
144
|
+
client,
|
|
145
|
+
waitForNextMessage: async (options?: { timeout?: number }) => {
|
|
146
|
+
if (nextMessage == null) {
|
|
147
|
+
await nextMessageTrigger.wait(options);
|
|
148
|
+
}
|
|
149
|
+
const result = nextMessage!;
|
|
150
|
+
nextMessageTrigger.reset();
|
|
151
|
+
nextMessage = null;
|
|
152
|
+
return result;
|
|
319
153
|
},
|
|
154
|
+
waitForPeer: (peerId: PublicKey) => waitForCondition({ condition: () => peers.has(peerId) }),
|
|
320
155
|
};
|
|
321
|
-
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const createMessage = (from: TestPeer, to: TestPeer, payload: any = PAYLOAD) => {
|
|
160
|
+
return {
|
|
161
|
+
author: from.id,
|
|
162
|
+
recipient: to.id,
|
|
163
|
+
payload: PAYLOAD,
|
|
164
|
+
};
|
|
165
|
+
};
|
|
322
166
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
167
|
+
const waitForSubscription = async (signal: SignalClient, peerId: PublicKey) => {
|
|
168
|
+
await asyncTimeout(
|
|
169
|
+
signal.localState.reconciled.waitForCondition(() => signal.localState.messageStreams.has(peerId)),
|
|
170
|
+
500,
|
|
171
|
+
);
|
|
172
|
+
};
|
|
328
173
|
});
|
|
174
|
+
|
|
175
|
+
interface TestPeer {
|
|
176
|
+
id: PublicKey;
|
|
177
|
+
client: SignalClient;
|
|
178
|
+
waitForNextMessage: (options?: { timeout?: number }) => Promise<any>;
|
|
179
|
+
waitForPeer: (peerId: PublicKey) => Promise<boolean>;
|
|
180
|
+
}
|