@dxos/messaging 0.6.8-main.3be982f → 0.6.8-staging.77f93a3

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 (60) hide show
  1. package/dist/lib/browser/index.mjs +466 -199
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +456 -197
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/types/src/messenger.blueprint-test.d.ts +4 -0
  8. package/dist/types/src/messenger.blueprint-test.d.ts.map +1 -0
  9. package/dist/types/src/messenger.d.ts +4 -10
  10. package/dist/types/src/messenger.d.ts.map +1 -1
  11. package/dist/types/src/signal-client/signal-client.d.ts +6 -10
  12. package/dist/types/src/signal-client/signal-client.d.ts.map +1 -1
  13. package/dist/types/src/signal-client/signal-local-state.d.ts +2 -10
  14. package/dist/types/src/signal-client/signal-local-state.d.ts.map +1 -1
  15. package/dist/types/src/signal-manager/edge-signal-manager.d.ts +18 -19
  16. package/dist/types/src/signal-manager/edge-signal-manager.d.ts.map +1 -1
  17. package/dist/types/src/signal-manager/index.d.ts +1 -0
  18. package/dist/types/src/signal-manager/index.d.ts.map +1 -1
  19. package/dist/types/src/signal-manager/memory-signal-manager.d.ts +14 -25
  20. package/dist/types/src/signal-manager/memory-signal-manager.d.ts.map +1 -1
  21. package/dist/types/src/signal-manager/signal-manager.d.ts +5 -6
  22. package/dist/types/src/signal-manager/signal-manager.d.ts.map +1 -1
  23. package/dist/types/src/signal-manager/websocket-signal-manager.d.ts +14 -29
  24. package/dist/types/src/signal-manager/websocket-signal-manager.d.ts.map +1 -1
  25. package/dist/types/src/signal-methods.d.ts +29 -14
  26. package/dist/types/src/signal-methods.d.ts.map +1 -1
  27. package/dist/types/src/testing/index.d.ts +5 -0
  28. package/dist/types/src/testing/index.d.ts.map +1 -0
  29. package/dist/types/src/testing/test-builder.d.ts +19 -0
  30. package/dist/types/src/testing/test-builder.d.ts.map +1 -0
  31. package/dist/types/src/testing/test-messages.d.ts +6 -0
  32. package/dist/types/src/testing/test-messages.d.ts.map +1 -0
  33. package/dist/types/src/testing/test-peer.d.ts +23 -0
  34. package/dist/types/src/testing/test-peer.d.ts.map +1 -0
  35. package/dist/types/src/testing/utils.d.ts +10 -0
  36. package/dist/types/src/testing/utils.d.ts.map +1 -0
  37. package/package.json +15 -14
  38. package/src/messenger.blueprint-test.ts +346 -0
  39. package/src/messenger.test.ts +26 -362
  40. package/src/messenger.ts +20 -18
  41. package/src/signal-client/signal-client-monitor.ts +3 -3
  42. package/src/signal-client/signal-client.test.ts +56 -52
  43. package/src/signal-client/signal-client.ts +30 -16
  44. package/src/signal-client/signal-local-state.ts +28 -10
  45. package/src/signal-manager/edge-signal-manager.test.ts +31 -35
  46. package/src/signal-manager/edge-signal-manager.ts +88 -36
  47. package/src/signal-manager/index.ts +1 -0
  48. package/src/signal-manager/memory-signal-manager.ts +36 -50
  49. package/src/signal-manager/signal-manager.ts +5 -7
  50. package/src/signal-manager/websocket-signal-manager.test.ts +27 -31
  51. package/src/signal-manager/websocket-signal-manager.ts +34 -65
  52. package/src/signal-methods.ts +33 -11
  53. package/src/testing/index.ts +8 -0
  54. package/src/testing/test-builder.ts +54 -0
  55. package/src/testing/test-messages.ts +24 -0
  56. package/src/testing/test-peer.ts +66 -0
  57. package/src/testing/utils.ts +50 -0
  58. package/dist/types/src/testing.d.ts +0 -40
  59. package/dist/types/src/testing.d.ts.map +0 -1
  60. package/src/testing.ts +0 -120
@@ -5,8 +5,8 @@
5
5
  // eslint-disable-next-line @typescript-eslint/no-var-requires
6
6
  import { expect } from 'earljs';
7
7
 
8
- import { Trigger, asyncTimeout, waitForCondition } from '@dxos/async';
9
- import { type TaggedType } from '@dxos/codec-protobuf';
8
+ import { asyncTimeout, waitForCondition } from '@dxos/async';
9
+ import { type Any, type TaggedType } from '@dxos/codec-protobuf';
10
10
  import { PublicKey } from '@dxos/keys';
11
11
  import { type TYPES } from '@dxos/protocols';
12
12
  import { runTestSignalServer, type SignalServerRunner } from '@dxos/signal';
@@ -14,10 +14,11 @@ import { afterAll, beforeAll, describe, test, afterTest } from '@dxos/test';
14
14
  import { ComplexSet, range } from '@dxos/util';
15
15
 
16
16
  import { SignalClient } from './signal-client';
17
+ import { type Message, type PeerInfo } from '../signal-methods';
17
18
 
18
19
  const PAYLOAD: TaggedType<TYPES, 'google.protobuf.Any'> = {
19
20
  '@type': 'google.protobuf.Any',
20
- type_url: 'dxos.Example',
21
+ type_url: 'google.protobuf.Any',
21
22
  value: Buffer.from('1'),
22
23
  };
23
24
 
@@ -35,70 +36,76 @@ describe('SignalClient', () => {
35
36
  test('message between 2 clients', async () => {
36
37
  const [peer1, peer2] = setupPeers({ peerCount: 2 });
37
38
 
38
- await peer1.client.subscribeMessages(peer1.id);
39
- await waitForSubscription(peer1.client, peer1.id);
39
+ await peer1.client.subscribeMessages(peer1.peerInfo);
40
+ await waitForSubscription(peer1.client, peer1.peerKey);
40
41
 
41
42
  const message = createMessage(peer2, peer1);
43
+ const receivedMessage = peer1.waitForNextMessage();
42
44
  await peer2.client.sendMessage(message);
43
- expect(await peer1.waitForNextMessage()).toEqual(message);
44
- }).timeout(500);
45
+ expect(await receivedMessage).toEqual(message);
46
+ });
45
47
 
46
48
  test('join', async () => {
47
49
  const topic = PublicKey.random();
48
50
  const [peer1, peer2] = setupPeers({ peerCount: 2 });
49
51
 
50
- await peer1.client.join({ topic, peerId: peer1.id });
51
- await peer2.client.join({ topic, peerId: peer2.id });
52
+ await peer1.client.join({ topic, peer: peer1.peerInfo });
53
+ await peer2.client.join({ topic, peer: peer2.peerInfo });
52
54
 
53
- await peer1.waitForPeer(peer2.id);
54
- await peer2.waitForPeer(peer1.id);
55
- }).timeout(500);
55
+ await peer1.waitForPeer(peer2.peerKey);
56
+ await peer2.waitForPeer(peer1.peerKey);
57
+ });
56
58
 
57
59
  test('signal to self', async () => {
58
60
  const [peer1, peer2] = setupPeers({ peerCount: 2 });
59
61
 
60
- await peer1.client.subscribeMessages(peer1.id);
61
- await waitForSubscription(peer1.client, peer1.id);
62
+ await peer1.client.subscribeMessages(peer1.peerInfo);
63
+ await waitForSubscription(peer1.client, peer1.peerKey);
62
64
 
63
65
  const message = createMessage(peer2, peer1);
66
+ const receivedMessage = peer1.waitForNextMessage();
67
+
64
68
  await peer1.client.sendMessage(message);
65
- expect(await peer1.waitForNextMessage()).toEqual(message);
66
- }).timeout(500);
69
+ expect(await receivedMessage).toEqual(message);
70
+ });
67
71
 
68
72
  test('unsubscribe from messages', async () => {
69
73
  const [peer1, peer2] = setupPeers({ peerCount: 2 });
70
74
 
71
- await peer1.client.subscribeMessages(peer1.id);
72
- await peer2.client.subscribeMessages(peer2.id);
73
- await waitForSubscription(peer1.client, peer1.id);
75
+ await peer1.client.subscribeMessages(peer1.peerInfo);
76
+ await peer2.client.subscribeMessages(peer2.peerInfo);
77
+ await waitForSubscription(peer1.client, peer1.peerKey);
74
78
 
75
79
  const message = createMessage(peer2, peer1);
76
80
 
77
81
  {
82
+ const receivedMessage = peer1.waitForNextMessage();
78
83
  await peer2.client.sendMessage(message);
79
- expect(await peer1.waitForNextMessage()).toEqual(message);
84
+ expect(await receivedMessage).toEqual(message);
80
85
  }
81
86
 
82
87
  // unsubscribing.
83
- await peer1.client.unsubscribeMessages(peer1.id);
88
+ await peer1.client.unsubscribeMessages(peer1.peerInfo);
84
89
 
85
90
  {
91
+ const receivedMessage = peer1.waitForNextMessage({ timeout: 200 });
86
92
  await peer2.client.sendMessage(message);
87
- await expect(peer1.waitForNextMessage({ timeout: 200 })).toBeRejected();
93
+ await expect(receivedMessage).toBeRejected();
88
94
  }
89
- }).timeout(1_500);
95
+ });
90
96
 
91
97
  test('signal after re-entrance', async () => {
92
98
  const [peer1, peer2] = setupPeers({ peerCount: 2 });
93
99
 
94
100
  const message = createMessage(peer2, peer1);
95
101
 
96
- await peer1.client.subscribeMessages(peer1.id);
97
- await waitForSubscription(peer1.client, peer1.id);
102
+ await peer1.client.subscribeMessages(peer1.peerInfo);
103
+ await waitForSubscription(peer1.client, peer1.peerKey);
98
104
 
99
105
  {
106
+ const waitMessage = peer1.waitForNextMessage();
100
107
  await peer2.client.sendMessage(message);
101
- expect(await peer1.waitForNextMessage()).toEqual(message);
108
+ expect(await waitMessage).toEqual(message);
102
109
  }
103
110
 
104
111
  //
@@ -107,30 +114,26 @@ describe('SignalClient', () => {
107
114
 
108
115
  await peer1.client.close();
109
116
  await peer1.client.open();
110
- await waitForSubscription(peer1.client, peer1.id);
117
+ await waitForSubscription(peer1.client, peer1.peerKey);
111
118
 
112
119
  {
120
+ const waitMessage = peer1.waitForNextMessage();
113
121
  await peer2.client.sendMessage(message);
114
- expect(await peer1.waitForNextMessage()).toEqual(message);
122
+ expect(await waitMessage).toEqual(message);
115
123
  }
116
- }).timeout(1_000);
124
+ });
117
125
 
118
126
  const setupPeers = (options?: { broker?: SignalServerRunner; peerCount?: number }): TestPeer[] => {
119
127
  return range(options?.peerCount ?? 1, () => {
120
128
  const peers = new ComplexSet(PublicKey.hash);
121
- let nextMessage: any | null = null;
122
- const nextMessageTrigger = new Trigger();
123
- const id = PublicKey.random();
129
+ const peerKey = PublicKey.random();
130
+ const identityKey = PublicKey.random();
124
131
  const client = new SignalClient((options?.broker ?? broker1).url());
125
- client.onMessage.on(async (msg) => {
126
- nextMessage = msg;
127
- nextMessageTrigger.wake();
128
- });
129
- client.swarmEvent.on(async ({ swarmEvent }) => {
132
+ client.swarmEvent.on(async (swarmEvent) => {
130
133
  if (swarmEvent.peerAvailable) {
131
- peers.add(PublicKey.from(swarmEvent.peerAvailable.peer));
134
+ peers.add(PublicKey.from(swarmEvent.peerAvailable.peer.peerKey));
132
135
  } else if (swarmEvent.peerLeft) {
133
- peers.delete(PublicKey.from(swarmEvent.peerLeft.peer));
136
+ peers.delete(PublicKey.from(swarmEvent.peerLeft.peer.peerKey));
134
137
  }
135
138
  });
136
139
 
@@ -139,26 +142,25 @@ describe('SignalClient', () => {
139
142
  await client.close();
140
143
  });
141
144
  return {
142
- id,
145
+ peerKey,
146
+ identityKey,
143
147
  client,
144
- waitForNextMessage: async (options?: { timeout?: number }) => {
145
- if (nextMessage == null) {
146
- await nextMessageTrigger.wait(options);
147
- }
148
- const result = nextMessage!;
149
- nextMessageTrigger.reset();
150
- nextMessage = null;
151
- return result;
148
+ peerInfo: { peerKey: peerKey.toHex(), identityKey: identityKey.toHex() },
149
+ waitForNextMessage: async () => {
150
+ return asyncTimeout(
151
+ client.onMessage.waitFor(() => true),
152
+ 5000,
153
+ );
152
154
  },
153
155
  waitForPeer: (peerId: PublicKey) => waitForCondition({ condition: () => peers.has(peerId) }),
154
156
  };
155
157
  });
156
158
  };
157
159
 
158
- const createMessage = (from: TestPeer, to: TestPeer, payload: any = PAYLOAD) => {
160
+ const createMessage = (from: TestPeer, to: TestPeer, payload: Any = PAYLOAD): Message => {
159
161
  return {
160
- author: from.id,
161
- recipient: to.id,
162
+ author: { peerKey: from.peerKey.toHex() },
163
+ recipient: { peerKey: to.peerKey.toHex() },
162
164
  payload: PAYLOAD,
163
165
  };
164
166
  };
@@ -172,8 +174,10 @@ describe('SignalClient', () => {
172
174
  });
173
175
 
174
176
  interface TestPeer {
175
- id: PublicKey;
177
+ peerKey: PublicKey;
178
+ identityKey: PublicKey;
176
179
  client: SignalClient;
180
+ peerInfo: PeerInfo;
177
181
  waitForNextMessage: (options?: { timeout?: number }) => Promise<any>;
178
182
  waitForPeer: (peerId: PublicKey) => Promise<boolean>;
179
183
  }
@@ -8,12 +8,18 @@ import { invariant } from '@dxos/invariant';
8
8
  import { PublicKey } from '@dxos/keys';
9
9
  import { log } from '@dxos/log';
10
10
  import { trace } from '@dxos/protocols';
11
- import { SignalState, type SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';
11
+ import { SignalState } from '@dxos/protocols/proto/dxos/mesh/signal';
12
12
 
13
13
  import { SignalClientMonitor } from './signal-client-monitor';
14
14
  import { SignalLocalState } from './signal-local-state';
15
15
  import { SignalRPCClient } from './signal-rpc-client';
16
- import { type Message, type SignalClientMethods, type SignalStatus } from '../signal-methods';
16
+ import {
17
+ type PeerInfo,
18
+ type Message,
19
+ type SignalClientMethods,
20
+ type SignalStatus,
21
+ type SwarmEvent,
22
+ } from '../signal-methods';
17
23
 
18
24
  const DEFAULT_RECONNECT_TIMEOUT = 100;
19
25
  const MAX_RECONNECT_TIMEOUT = 5_000;
@@ -56,7 +62,7 @@ export class SignalClient extends Resource implements SignalClientMethods {
56
62
  readonly statusChanged = new Event<SignalStatus>();
57
63
 
58
64
  public readonly onMessage = new Event<Message>();
59
- public readonly swarmEvent = new Event<{ topic: PublicKey; swarmEvent: SwarmEvent }>();
65
+ public readonly swarmEvent = new Event<SwarmEvent>();
60
66
 
61
67
  /**
62
68
  * @param _host Signal server websocket URL.
@@ -162,36 +168,44 @@ export class SignalClient extends Resource implements SignalClientMethods {
162
168
  };
163
169
  }
164
170
 
165
- async join(args: { topic: PublicKey; peerId: PublicKey }): Promise<void> {
166
- log('joining', { topic: args.topic, peerId: args.peerId });
171
+ async join(args: { topic: PublicKey; peer: PeerInfo }): Promise<void> {
172
+ log('joining', { topic: args.topic, peerId: args.peer.peerKey });
167
173
  this._monitor.recordJoin();
168
- this.localState.join(args);
174
+ this.localState.join({ topic: args.topic, peerId: PublicKey.from(args.peer.peerKey) });
169
175
  this._reconcileTask?.schedule();
170
176
  }
171
177
 
172
- async leave(args: { topic: PublicKey; peerId: PublicKey }): Promise<void> {
173
- log('leaving', { topic: args.topic, peerId: args.peerId });
178
+ async leave(args: { topic: PublicKey; peer: PeerInfo }): Promise<void> {
179
+ log('leaving', { topic: args.topic, peerId: args.peer.peerKey });
174
180
  this._monitor.recordLeave();
175
- this.localState.leave(args);
181
+ this.localState.leave({ topic: args.topic, peerId: PublicKey.from(args.peer.peerKey) });
176
182
  }
177
183
 
178
184
  async sendMessage(msg: Message): Promise<void> {
179
185
  return this._monitor.recordMessageSending(msg, async () => {
180
186
  await this._clientReady.wait();
181
187
  invariant(this._state === SignalState.CONNECTED, 'Not connected to Signal Server');
182
- await this._client!.sendMessage(msg);
188
+ invariant(msg.author.peerKey, 'Author key required');
189
+ invariant(msg.recipient.peerKey, 'Recipient key required');
190
+ await this._client!.sendMessage({
191
+ author: PublicKey.from(msg.author.peerKey),
192
+ recipient: PublicKey.from(msg.recipient.peerKey),
193
+ payload: msg.payload,
194
+ });
183
195
  });
184
196
  }
185
197
 
186
- async subscribeMessages(peerId: PublicKey) {
187
- log('subscribing to messages', { peerId });
188
- this.localState.subscribeMessages(peerId);
198
+ async subscribeMessages(peer: PeerInfo) {
199
+ invariant(peer.peerKey, 'Peer key required');
200
+ log('subscribing to messages', { peer });
201
+ this.localState.subscribeMessages(PublicKey.from(peer.peerKey));
189
202
  this._reconcileTask?.schedule();
190
203
  }
191
204
 
192
- async unsubscribeMessages(peerId: PublicKey) {
193
- log('unsubscribing from messages', { peerId });
194
- this.localState.unsubscribeMessages(peerId);
205
+ async unsubscribeMessages(peer: PeerInfo) {
206
+ invariant(peer.peerKey, 'Peer key required');
207
+ log('unsubscribing from messages', { peer });
208
+ this.localState.unsubscribeMessages(PublicKey.from(peer.peerKey));
195
209
  }
196
210
 
197
211
  private _scheduleReconcileAfterError() {
@@ -3,21 +3,24 @@
3
3
  //
4
4
 
5
5
  import { asyncTimeout, Event } from '@dxos/async';
6
- import type { Any, Stream } from '@dxos/codec-protobuf';
6
+ import type { Stream } from '@dxos/codec-protobuf';
7
7
  import { cancelWithContext, type Context } from '@dxos/context';
8
8
  import { PublicKey } from '@dxos/keys';
9
9
  import { log } from '@dxos/log';
10
- import { type Message as SignalMessage, type SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';
10
+ import {
11
+ type Message as SignalMessage,
12
+ type SwarmEvent as SwarmEventProto,
13
+ } from '@dxos/protocols/proto/dxos/mesh/signal';
11
14
  import { ComplexMap, ComplexSet, safeAwaitAll } from '@dxos/util';
12
15
 
13
16
  import { type SignalRPCClient } from './signal-rpc-client';
14
- import type { Message } from '../signal-methods';
17
+ import type { Message, SwarmEvent } from '../signal-methods';
15
18
 
16
19
  export class SignalLocalState {
17
20
  /**
18
21
  * Swarm events streams. Keys represent actually joined topic and peerId.
19
22
  */
20
- private readonly _swarmStreams = new ComplexMap<{ topic: PublicKey; peerId: PublicKey }, Stream<SwarmEvent>>(
23
+ private readonly _swarmStreams = new ComplexMap<{ topic: PublicKey; peerId: PublicKey }, Stream<SwarmEventProto>>(
21
24
  ({ topic, peerId }) => topic.toHex() + peerId.toHex(),
22
25
  );
23
26
 
@@ -46,8 +49,8 @@ export class SignalLocalState {
46
49
  readonly reconciled = new Event();
47
50
 
48
51
  constructor(
49
- private readonly _onMessage: (params: { author: PublicKey; recipient: PublicKey; payload: Any }) => Promise<void>,
50
- private readonly _onSwarmEvent: (params: { topic: PublicKey; swarmEvent: SwarmEvent }) => Promise<void>,
52
+ private readonly _onMessage: (params: Message) => Promise<void>,
53
+ private readonly _onSwarmEvent: (params: SwarmEvent) => Promise<void>,
51
54
  ) {}
52
55
 
53
56
  async safeCloseStreams(): Promise<{ failureCount: number }> {
@@ -107,10 +110,25 @@ export class SignalLocalState {
107
110
  const swarmStream = await asyncTimeout(cancelWithContext(ctx, client.join({ topic, peerId })), 5_000);
108
111
  // Subscribing to swarm events.
109
112
  // TODO(mykola): What happens when the swarm stream is closed? Maybe send leave event for each peer?
110
- swarmStream.subscribe(async (swarmEvent: SwarmEvent) => {
113
+ swarmStream.subscribe(async (swarmEvent: SwarmEventProto) => {
111
114
  if (this._joinedTopics.has({ topic, peerId })) {
112
115
  log('swarm event', { swarmEvent });
113
- await this._onSwarmEvent({ topic, swarmEvent });
116
+ const event: SwarmEvent = swarmEvent.peerAvailable
117
+ ? {
118
+ topic,
119
+ peerAvailable: {
120
+ ...swarmEvent.peerAvailable,
121
+ peer: { peerKey: PublicKey.from(swarmEvent.peerAvailable.peer).toHex() },
122
+ },
123
+ }
124
+ : {
125
+ topic,
126
+ peerLeft: {
127
+ ...swarmEvent.peerLeft,
128
+ peer: { peerKey: PublicKey.from(swarmEvent.peerLeft!.peer).toHex() },
129
+ },
130
+ };
131
+ await this._onSwarmEvent(event);
114
132
  }
115
133
  });
116
134
 
@@ -141,8 +159,8 @@ export class SignalLocalState {
141
159
  messageStream.subscribe(async (signalMessage: SignalMessage) => {
142
160
  if (this._subscribedMessages.has({ peerId })) {
143
161
  const message: Message = {
144
- author: PublicKey.from(signalMessage.author),
145
- recipient: PublicKey.from(signalMessage.recipient),
162
+ author: { peerKey: PublicKey.from(signalMessage.author).toHex() },
163
+ recipient: { peerKey: PublicKey.from(signalMessage.recipient).toHex() },
146
164
  payload: signalMessage.payload,
147
165
  };
148
166
  await this._onMessage(message);
@@ -3,68 +3,64 @@
3
3
  //
4
4
  import { EdgeClient } from '@dxos/edge-client';
5
5
  import { PublicKey } from '@dxos/keys';
6
- import { describe, openAndClose, test } from '@dxos/test';
6
+ import { afterTest, describe, openAndClose, test } from '@dxos/test';
7
7
 
8
- import { EdgeSignal } from './edge-signal-manager';
9
- import { type Message } from '../signal-methods';
10
- import { expectPeerAvailable, expectPeerLeft, expectReceivedMessage } from '../testing';
8
+ import { EdgeSignalManager } from './edge-signal-manager';
9
+ import { createMessage, expectReceivedMessage, TestBuilder, type TestBuilderOptions } from '../testing';
11
10
 
12
- // TODO(mykola): Expects wrangler dev on edge repo to run. Skip to pass CI.
11
+ // TODO(mykola): Expects wrangler dev in edge repo to run. Skip to pass CI.
13
12
  describe.skip('EdgeSignalManager', () => {
14
- const setupPeer = async () => {
15
- const [identityKey, deviceKey] = PublicKey.randomSequence();
16
-
13
+ const edgeSignalFactory: TestBuilderOptions['signalManagerFactory'] = async (identityKey, deviceKey) => {
17
14
  const client = new EdgeClient(identityKey, deviceKey, { socketEndpoint: 'ws://localhost:8787' });
18
15
  await openAndClose(client);
19
- const edgeSignal = new EdgeSignal({ messengerClient: client });
20
- await openAndClose(edgeSignal);
21
16
 
22
- return { identityKey, deviceKey, client, edgeSignal };
17
+ return new EdgeSignalManager({ edgeConnection: client });
23
18
  };
24
19
 
25
20
  test('two peers discover each other', async () => {
21
+ const builder = new TestBuilder({ signalManagerFactory: edgeSignalFactory });
22
+ afterTest(() => builder.close());
23
+ const [peer1, peer2] = await builder.createPeers(2);
24
+
26
25
  const topic = PublicKey.random();
27
- const peer1 = await setupPeer();
28
- const peer2 = await setupPeer();
29
26
 
30
- const discover12 = expectPeerAvailable(peer1.edgeSignal, topic, peer2.deviceKey);
31
- const discover21 = expectPeerAvailable(peer2.edgeSignal, topic, peer1.deviceKey);
27
+ const discover12 = peer1.waitForPeerAvailable(topic, peer2.peerInfo);
28
+ const discover21 = peer2.waitForPeerAvailable(topic, peer1.peerInfo);
32
29
 
33
- await peer1.edgeSignal.join({ topic, peerId: peer1.deviceKey });
34
- await peer2.edgeSignal.join({ topic, peerId: peer2.deviceKey });
30
+ await peer1.signalManager.join({ topic, peer: peer1.peerInfo });
31
+ await peer2.signalManager.join({ topic, peer: peer2.peerInfo });
35
32
 
36
33
  await discover12;
37
34
  await discover21;
38
35
  });
39
36
 
40
37
  test('join and leave swarm', async () => {
38
+ const builder = new TestBuilder({ signalManagerFactory: edgeSignalFactory });
39
+ afterTest(() => builder.close());
40
+ const [peer1, peer2] = await builder.createPeers(2);
41
+
41
42
  const topic = PublicKey.random();
42
- const peer1 = await setupPeer();
43
- const peer2 = await setupPeer();
44
43
 
45
- const discover12 = expectPeerAvailable(peer1.edgeSignal, topic, peer2.deviceKey);
46
- const left12 = expectPeerLeft(peer1.edgeSignal, topic, peer2.deviceKey);
44
+ const discover12 = peer1.waitForPeerAvailable(topic, peer2.peerInfo);
45
+ const left12 = peer1.waitForPeerLeft(topic, peer2.peerInfo);
47
46
 
48
- await peer1.edgeSignal.join({ topic, peerId: peer1.deviceKey });
49
- await peer2.edgeSignal.join({ topic, peerId: peer2.deviceKey });
47
+ await peer2.signalManager.join({ topic, peer: peer2.peerInfo });
48
+ await peer1.signalManager.join({ topic, peer: peer1.peerInfo });
50
49
  await discover12;
51
50
 
52
- await peer2.edgeSignal.leave({ topic, peerId: peer2.deviceKey });
51
+ await peer2.signalManager.leave({ topic, peer: peer2.peerInfo });
53
52
  await left12;
54
53
  });
55
54
 
56
55
  test('message between peers', async () => {
57
- const peer1 = await setupPeer();
58
- const peer2 = await setupPeer();
59
- const message: Message = {
60
- author: peer1.deviceKey,
61
- recipient: peer2.deviceKey,
62
- payload: { type_url: 'google.protobuf.Any', value: Uint8Array.from([1, 2, 3]) },
63
- };
64
-
65
- const receivedMessage = expectReceivedMessage(peer2.edgeSignal, message);
66
- await peer2.edgeSignal.subscribeMessages(peer2.deviceKey);
67
- await peer1.edgeSignal.sendMessage(message);
56
+ const builder = new TestBuilder({ signalManagerFactory: edgeSignalFactory });
57
+ afterTest(() => builder.close());
58
+ const [peer1, peer2] = await builder.createPeers(2);
59
+ const message = createMessage(peer1.peerInfo, peer2.peerInfo);
60
+
61
+ const receivedMessage = expectReceivedMessage(peer2.signalManager.onMessage, message);
62
+ await peer2.signalManager.subscribeMessages(peer2.peerInfo);
63
+ await peer1.signalManager.sendMessage(message);
68
64
 
69
65
  await receivedMessage;
70
66
  });