@dxos/network-manager 2.33.9-dev.002e8917 → 2.33.9-dev.227ba79d

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 (151) hide show
  1. package/dist/src/network-manager.blueprint-test.d.ts +3 -1
  2. package/dist/src/network-manager.blueprint-test.d.ts.map +1 -1
  3. package/dist/src/network-manager.blueprint-test.js +46 -17
  4. package/dist/src/network-manager.blueprint-test.js.map +1 -1
  5. package/dist/src/network-manager.browser-test.js +1 -1
  6. package/dist/src/network-manager.browser-test.js.map +1 -1
  7. package/dist/src/network-manager.d.ts.map +1 -1
  8. package/dist/src/network-manager.js +6 -6
  9. package/dist/src/network-manager.js.map +1 -1
  10. package/dist/src/network-manager.test.js +5 -4
  11. package/dist/src/network-manager.test.js.map +1 -1
  12. package/dist/src/proto/gen/dxos/credentials.d.ts +39 -0
  13. package/dist/src/proto/gen/dxos/credentials.d.ts.map +1 -1
  14. package/dist/src/proto/gen/dxos/halo/keys.d.ts +44 -2
  15. package/dist/src/proto/gen/dxos/halo/keys.d.ts.map +1 -1
  16. package/dist/src/proto/gen/dxos/halo/keys.js +4 -0
  17. package/dist/src/proto/gen/dxos/halo/keys.js.map +1 -1
  18. package/dist/src/proto/gen/dxos/mesh/signal.d.ts +74 -37
  19. package/dist/src/proto/gen/dxos/mesh/signal.d.ts.map +1 -1
  20. package/dist/src/proto/gen/dxos/mesh/signalMessage.d.ts +79 -0
  21. package/dist/src/proto/gen/dxos/mesh/signalMessage.d.ts.map +1 -0
  22. package/dist/src/proto/gen/dxos/mesh/signalMessage.js +3 -0
  23. package/dist/src/proto/gen/dxos/mesh/signalMessage.js.map +1 -0
  24. package/dist/src/proto/gen/google/protobuf.d.ts +8 -2
  25. package/dist/src/proto/gen/google/protobuf.d.ts.map +1 -1
  26. package/dist/src/proto/gen/index.d.ts +17 -5
  27. package/dist/src/proto/gen/index.d.ts.map +1 -1
  28. package/dist/src/proto/gen/index.js +1 -1
  29. package/dist/src/proto/gen/index.js.map +1 -1
  30. package/dist/src/proto/substitutions.d.ts +4 -0
  31. package/dist/src/proto/substitutions.d.ts.map +1 -1
  32. package/dist/src/proto/substitutions.js +3 -1
  33. package/dist/src/proto/substitutions.js.map +1 -1
  34. package/dist/src/signal/in-memory-signal-manager.d.ts +7 -7
  35. package/dist/src/signal/in-memory-signal-manager.d.ts.map +1 -1
  36. package/dist/src/signal/in-memory-signal-manager.js +29 -8
  37. package/dist/src/signal/in-memory-signal-manager.js.map +1 -1
  38. package/dist/src/signal/index.d.ts +1 -2
  39. package/dist/src/signal/index.d.ts.map +1 -1
  40. package/dist/src/signal/index.js +1 -2
  41. package/dist/src/signal/index.js.map +1 -1
  42. package/dist/src/signal/integration.test.d.ts +2 -0
  43. package/dist/src/signal/integration.test.d.ts.map +1 -0
  44. package/dist/src/signal/integration.test.js +102 -0
  45. package/dist/src/signal/integration.test.js.map +1 -0
  46. package/dist/src/signal/message-router.d.ts +7 -7
  47. package/dist/src/signal/message-router.d.ts.map +1 -1
  48. package/dist/src/signal/message-router.js +6 -1
  49. package/dist/src/signal/message-router.js.map +1 -1
  50. package/dist/src/signal/message-router.test.js +15 -19
  51. package/dist/src/signal/message-router.test.js.map +1 -1
  52. package/dist/src/signal/signal-client.d.ts +33 -18
  53. package/dist/src/signal/signal-client.d.ts.map +1 -1
  54. package/dist/src/signal/signal-client.js +102 -92
  55. package/dist/src/signal/signal-client.js.map +1 -1
  56. package/dist/src/signal/signal-client.test.js +60 -77
  57. package/dist/src/signal/signal-client.test.js.map +1 -1
  58. package/dist/src/signal/{websocket-signal-manager.d.ts → signal-manager-impl.d.ts} +13 -11
  59. package/dist/src/signal/signal-manager-impl.d.ts.map +1 -0
  60. package/dist/src/signal/signal-manager-impl.js +151 -0
  61. package/dist/src/signal/signal-manager-impl.js.map +1 -0
  62. package/dist/src/signal/signal-manager.d.ts +12 -11
  63. package/dist/src/signal/signal-manager.d.ts.map +1 -1
  64. package/dist/src/signal/signal-rpc-client.d.ts +19 -0
  65. package/dist/src/signal/signal-rpc-client.d.ts.map +1 -0
  66. package/dist/src/signal/signal-rpc-client.js +108 -0
  67. package/dist/src/signal/signal-rpc-client.js.map +1 -0
  68. package/dist/src/signal/signal-rpc-client.test.d.ts +2 -0
  69. package/dist/src/signal/signal-rpc-client.test.d.ts.map +1 -0
  70. package/dist/src/signal/signal-rpc-client.test.js +74 -0
  71. package/dist/src/signal/signal-rpc-client.test.js.map +1 -0
  72. package/dist/src/swarm/connection.d.ts +3 -3
  73. package/dist/src/swarm/connection.d.ts.map +1 -1
  74. package/dist/src/swarm/connection.js +1 -4
  75. package/dist/src/swarm/connection.js.map +1 -1
  76. package/dist/src/swarm/swarm.d.ts +6 -7
  77. package/dist/src/swarm/swarm.d.ts.map +1 -1
  78. package/dist/src/swarm/swarm.js +21 -17
  79. package/dist/src/swarm/swarm.js.map +1 -1
  80. package/dist/src/swarm/swarm.test.js +156 -117
  81. package/dist/src/swarm/swarm.test.js.map +1 -1
  82. package/dist/src/topology/fully-connected-topology.d.ts +0 -1
  83. package/dist/src/topology/fully-connected-topology.d.ts.map +1 -1
  84. package/dist/src/topology/fully-connected-topology.js +1 -6
  85. package/dist/src/topology/fully-connected-topology.js.map +1 -1
  86. package/dist/src/topology/mmst-topology.d.ts +0 -1
  87. package/dist/src/topology/mmst-topology.d.ts.map +1 -1
  88. package/dist/src/topology/mmst-topology.js +1 -6
  89. package/dist/src/topology/mmst-topology.js.map +1 -1
  90. package/dist/src/topology/star-topology.d.ts +0 -1
  91. package/dist/src/topology/star-topology.d.ts.map +1 -1
  92. package/dist/src/topology/star-topology.js +1 -6
  93. package/dist/src/topology/star-topology.js.map +1 -1
  94. package/dist/src/topology/topology.d.ts +0 -6
  95. package/dist/src/topology/topology.d.ts.map +1 -1
  96. package/dist/src/transport/in-memory-transport.d.ts +2 -2
  97. package/dist/src/transport/in-memory-transport.d.ts.map +1 -1
  98. package/dist/src/transport/in-memory-transport.js.map +1 -1
  99. package/dist/src/transport/transport.d.ts +3 -3
  100. package/dist/src/transport/transport.d.ts.map +1 -1
  101. package/dist/src/transport/webrtc-transport.d.ts +3 -3
  102. package/dist/src/transport/webrtc-transport.d.ts.map +1 -1
  103. package/dist/src/transport/webrtc-transport.js.map +1 -1
  104. package/dist/tests-setup.js +1 -1
  105. package/dist/tsconfig.tsbuildinfo +1 -1
  106. package/package.json +14 -12
  107. package/src/network-manager.blueprint-test.ts +57 -22
  108. package/src/network-manager.browser-test.ts +1 -1
  109. package/src/network-manager.test.ts +8 -7
  110. package/src/network-manager.ts +8 -9
  111. package/src/proto/defs/dxos/mesh/signal.proto +53 -35
  112. package/src/proto/defs/dxos/mesh/signalMessage.proto +51 -0
  113. package/src/proto/gen/dxos/credentials.ts +40 -0
  114. package/src/proto/gen/dxos/halo/keys.ts +45 -2
  115. package/src/proto/gen/dxos/mesh/signal.ts +73 -37
  116. package/src/proto/gen/dxos/mesh/signalMessage.ts +83 -0
  117. package/src/proto/gen/google/protobuf.ts +9 -2
  118. package/src/proto/gen/index.ts +18 -6
  119. package/src/proto/substitutions.ts +3 -1
  120. package/src/signal/in-memory-signal-manager.ts +37 -12
  121. package/src/signal/index.ts +1 -2
  122. package/src/signal/integration.test.ts +117 -0
  123. package/src/signal/message-router.test.ts +36 -41
  124. package/src/signal/message-router.ts +22 -18
  125. package/src/signal/signal-client.test.ts +70 -92
  126. package/src/signal/signal-client.ts +119 -113
  127. package/src/signal/signal-manager-impl.ts +166 -0
  128. package/src/signal/signal-manager.ts +12 -12
  129. package/src/signal/signal-rpc-client.test.ts +86 -0
  130. package/src/signal/signal-rpc-client.ts +121 -0
  131. package/src/swarm/connection.ts +5 -8
  132. package/src/swarm/swarm.test.ts +208 -169
  133. package/src/swarm/swarm.ts +24 -20
  134. package/src/topology/fully-connected-topology.ts +1 -9
  135. package/src/topology/mmst-topology.ts +1 -9
  136. package/src/topology/star-topology.ts +1 -7
  137. package/src/topology/topology.ts +0 -7
  138. package/src/transport/in-memory-transport.ts +2 -2
  139. package/src/transport/transport.ts +3 -3
  140. package/src/transport/webrtc-transport.ts +3 -3
  141. package/dist/browser-mocha/bundle.js +0 -119276
  142. package/dist/browser-mocha/main.js +0 -27
  143. package/dist/src/signal/websocket-rpc.d.ts +0 -30
  144. package/dist/src/signal/websocket-rpc.d.ts.map +0 -1
  145. package/dist/src/signal/websocket-rpc.js +0 -203
  146. package/dist/src/signal/websocket-rpc.js.map +0 -1
  147. package/dist/src/signal/websocket-signal-manager.d.ts.map +0 -1
  148. package/dist/src/signal/websocket-signal-manager.js +0 -134
  149. package/dist/src/signal/websocket-signal-manager.js.map +0 -1
  150. package/src/signal/websocket-rpc.ts +0 -208
  151. package/src/signal/websocket-signal-manager.ts +0 -158
@@ -2,51 +2,87 @@ import type { Stream } from "@dxos/codec-protobuf";
2
2
  import substitutions from "../../../substitutions";
3
3
  import * as dxos_credentials from "../credentials";
4
4
  import * as dxos_halo_keys from "../halo/keys";
5
+ import * as dxos_mesh_signalMessage from "./signalMessage";
5
6
  import * as google_protobuf from "../../google/protobuf";
7
+ /**
8
+ * Defined in:
9
+ * {@link file://./../../../defs/dxos/mesh/signal.proto}
10
+ */
11
+ export interface JoinRequest {
12
+ swarm: Uint8Array;
13
+ peer: Uint8Array;
14
+ }
15
+ /**
16
+ * Defined in:
17
+ * {@link file://./../../../defs/dxos/mesh/signal.proto}
18
+ */
6
19
  export interface Message {
20
+ author: Uint8Array;
21
+ recipient: Uint8Array;
22
+ payload: google_protobuf.Any;
23
+ }
24
+ /**
25
+ * Defined in:
26
+ * {@link file://./../../../defs/dxos/mesh/signal.proto}
27
+ */
28
+ export interface ReceptionRequest {
29
+ peer: Uint8Array;
30
+ }
31
+ /**
32
+ * Defined in:
33
+ * {@link file://./../../../defs/dxos/mesh/signal.proto}
34
+ */
35
+ export interface SwarmEvent {
36
+ peerAvailable?: SwarmEvent.PeerAvailable;
37
+ peerLeft?: SwarmEvent.PeerLeft;
38
+ }
39
+ export namespace SwarmEvent {
7
40
  /**
8
- * Sender's public key.
9
- */
10
- id?: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
11
- /**
12
- * Receiver`s public key.
13
- */
14
- remoteId?: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
15
- /**
16
- * Swarm identefier.
17
- */
18
- topic?: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
19
- /**
20
- * Unique connection identifier.
21
- */
22
- sessionId?: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
23
- /**
24
- * Message payload.
41
+ * Defined in:
42
+ * {@link file://./../../../defs/dxos/mesh/signal.proto}
25
43
  */
26
- data?: MessageData;
44
+ export interface PeerAvailable {
45
+ peer: Uint8Array;
46
+ since: ReturnType<(typeof substitutions)["google.protobuf.Timestamp"]["decode"]>;
47
+ /**
48
+ * Options:
49
+ * - proto3_optional = true
50
+ */
51
+ until?: ReturnType<(typeof substitutions)["google.protobuf.Timestamp"]["decode"]>;
52
+ /**
53
+ * Options:
54
+ * - proto3_optional = true
55
+ */
56
+ announceBackToHost?: Uint8Array;
57
+ }
27
58
  /**
28
- * Unique message identifier. Used for Acknolegment and matching Anwers to Offers.
59
+ * Defined in:
60
+ * {@link file://./../../../defs/dxos/mesh/signal.proto}
29
61
  */
30
- messageId?: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
62
+ export interface PeerLeft {
63
+ peer: Uint8Array;
64
+ }
31
65
  }
32
- export interface MessageData {
33
- offer?: Offer;
34
- answer?: Answer;
35
- signal?: Signal;
36
- ack?: Acknowledgement;
66
+ /**
67
+ * Defined in:
68
+ * {@link file://./../../../defs/dxos/mesh/signal.proto}
69
+ */
70
+ export interface HostEvent {
71
+ peerAvailable?: SwarmEvent.PeerAvailable;
37
72
  }
38
- export interface Offer {
39
- }
40
- export interface Answer {
41
- accept?: boolean;
42
- /**
43
- * MessageId of the Offer being answered.
44
- */
45
- offerMessageId?: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
73
+ /**
74
+ * Defined in:
75
+ * {@link file://./../../../defs/dxos/mesh/signal.proto}
76
+ */
77
+ export interface PeerEvent {
78
+ message?: Message;
46
79
  }
80
+ /**
81
+ * Defined in:
82
+ * {@link file://./../../../defs/dxos/mesh/signal.proto}
83
+ */
47
84
  export interface Signal {
48
- json?: string;
49
- }
50
- export interface Acknowledgement {
51
- messageId?: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
85
+ join: (request: JoinRequest) => Stream<SwarmEvent>;
86
+ receiveMessages: (request: ReceptionRequest) => Stream<Message>;
87
+ sendMessage: (request: Message) => Promise<void>;
52
88
  }
@@ -0,0 +1,83 @@
1
+ import type { Stream } from "@dxos/codec-protobuf";
2
+ import substitutions from "../../../substitutions";
3
+ import * as dxos_credentials from "../credentials";
4
+ import * as dxos_halo_keys from "../halo/keys";
5
+ import * as dxos_mesh_signal from "./signal";
6
+ import * as google_protobuf from "../../google/protobuf";
7
+ /**
8
+ * Defined in:
9
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
10
+ */
11
+ export interface SignalMessage {
12
+ /**
13
+ * Sender's public key.
14
+ */
15
+ id: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
16
+ /**
17
+ * Receiver`s public key.
18
+ */
19
+ remoteId: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
20
+ /**
21
+ * Swarm identefier.
22
+ */
23
+ topic: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
24
+ /**
25
+ * Unique connection identifier.
26
+ */
27
+ sessionId: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
28
+ /**
29
+ * Message payload.
30
+ */
31
+ data: MessageData;
32
+ /**
33
+ * Unique message identifier. Used for Acknolegment and matching Anwers to Offers.
34
+ *
35
+ * Options:
36
+ * - proto3_optional = true
37
+ */
38
+ messageId?: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
39
+ }
40
+ /**
41
+ * Defined in:
42
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
43
+ */
44
+ export interface MessageData {
45
+ offer?: Offer;
46
+ answer?: Answer;
47
+ signal?: Signal;
48
+ ack?: Acknowledgement;
49
+ }
50
+ /**
51
+ * Defined in:
52
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
53
+ */
54
+ export interface Offer {
55
+ }
56
+ /**
57
+ * Defined in:
58
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
59
+ */
60
+ export interface Answer {
61
+ accept: boolean;
62
+ /**
63
+ * MessageId of the Offer being answered.
64
+ *
65
+ * Options:
66
+ * - proto3_optional = true
67
+ */
68
+ offerMessageId?: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
69
+ }
70
+ /**
71
+ * Defined in:
72
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
73
+ */
74
+ export interface Signal {
75
+ json: string;
76
+ }
77
+ /**
78
+ * Defined in:
79
+ * {@link file://./../../../defs/dxos/mesh/signalMessage.proto}
80
+ */
81
+ export interface Acknowledgement {
82
+ messageId: ReturnType<(typeof substitutions)["dxos.halo.keys.PubKey"]["decode"]>;
83
+ }
@@ -3,7 +3,14 @@ import substitutions from "../../substitutions";
3
3
  import * as dxos_credentials from "../dxos/credentials";
4
4
  import * as dxos_halo_keys from "../dxos/halo/keys";
5
5
  import * as dxos_mesh_signal from "../dxos/mesh/signal";
6
+ import * as dxos_mesh_signalMessage from "../dxos/mesh/signalMessage";
6
7
  export interface Any {
7
- type_url?: string;
8
- value?: Uint8Array;
8
+ type_url: string;
9
+ value: Uint8Array;
10
+ }
11
+ export interface Empty {
12
+ }
13
+ export interface Timestamp {
14
+ seconds: string;
15
+ nanos: number;
9
16
  }
@@ -2,6 +2,7 @@ import { Schema } from "@dxos/codec-protobuf";
2
2
  import * as dxos_credentials from "./dxos/credentials";
3
3
  import * as dxos_halo_keys from "./dxos/halo/keys";
4
4
  import * as dxos_mesh_signal from "./dxos/mesh/signal";
5
+ import * as dxos_mesh_signalMessage from "./dxos/mesh/signalMessage";
5
6
  import * as google_protobuf from "./google/protobuf";
6
7
  import substitutions from "../substitutions";
7
8
  export interface TYPES {
@@ -15,15 +16,26 @@ export interface TYPES {
15
16
  "dxos.halo.keys.KeyType": dxos_halo_keys.KeyType;
16
17
  "dxos.halo.keys.PrivKey": dxos_halo_keys.PrivKey;
17
18
  "dxos.halo.keys.PubKey": dxos_halo_keys.PubKey;
18
- "dxos.mesh.signal.Acknowledgement": dxos_mesh_signal.Acknowledgement;
19
- "dxos.mesh.signal.Answer": dxos_mesh_signal.Answer;
19
+ "dxos.mesh.signal.HostEvent": dxos_mesh_signal.HostEvent;
20
+ "dxos.mesh.signal.JoinRequest": dxos_mesh_signal.JoinRequest;
20
21
  "dxos.mesh.signal.Message": dxos_mesh_signal.Message;
21
- "dxos.mesh.signal.MessageData": dxos_mesh_signal.MessageData;
22
- "dxos.mesh.signal.Offer": dxos_mesh_signal.Offer;
23
- "dxos.mesh.signal.Signal": dxos_mesh_signal.Signal;
22
+ "dxos.mesh.signal.PeerEvent": dxos_mesh_signal.PeerEvent;
23
+ "dxos.mesh.signal.ReceptionRequest": dxos_mesh_signal.ReceptionRequest;
24
+ "dxos.mesh.signal.SwarmEvent": dxos_mesh_signal.SwarmEvent;
25
+ "dxos.mesh.signal.SwarmEvent.PeerAvailable": dxos_mesh_signal.SwarmEvent.PeerAvailable;
26
+ "dxos.mesh.signal.SwarmEvent.PeerLeft": dxos_mesh_signal.SwarmEvent.PeerLeft;
27
+ "dxos.mesh.signalMessage.Acknowledgement": dxos_mesh_signalMessage.Acknowledgement;
28
+ "dxos.mesh.signalMessage.Answer": dxos_mesh_signalMessage.Answer;
29
+ "dxos.mesh.signalMessage.MessageData": dxos_mesh_signalMessage.MessageData;
30
+ "dxos.mesh.signalMessage.Offer": dxos_mesh_signalMessage.Offer;
31
+ "dxos.mesh.signalMessage.Signal": dxos_mesh_signalMessage.Signal;
32
+ "dxos.mesh.signalMessage.SignalMessage": dxos_mesh_signalMessage.SignalMessage;
24
33
  "google.protobuf.Any": google_protobuf.Any;
34
+ "google.protobuf.Empty": google_protobuf.Empty;
35
+ "google.protobuf.Timestamp": google_protobuf.Timestamp;
25
36
  }
26
37
  export interface SERVICES {
38
+ "dxos.mesh.signal.Signal": dxos_mesh_signal.Signal;
27
39
  }
28
- export const schemaJson = JSON.parse("{\"nested\":{\"dxos\":{\"nested\":{\"credentials\":{\"nested\":{\"Message\":{\"fields\":{\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":1,\"comment\":null}},\"comment\":null},\"SignedMessage\":{\"fields\":{\"signed\":{\"rule\":\"required\",\"type\":\"Signed\",\"id\":1,\"comment\":null},\"signatures\":{\"rule\":\"repeated\",\"type\":\"Signature\",\"id\":2,\"comment\":null}},\"nested\":{\"Signature\":{\"fields\":{\"key\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"signature\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":null},\"keyChain\":{\"type\":\"KeyChain\",\"id\":3,\"comment\":null}},\"comment\":null},\"Signed\":{\"fields\":{\"created\":{\"rule\":\"required\",\"type\":\"string\",\"id\":1,\"comment\":null},\"nonce\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":null},\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":10,\"comment\":null}},\"comment\":null}},\"comment\":\"A generic container message used whenever messages are signed (e.g. PartyCredential)\"}}},\"halo\":{\"nested\":{\"keys\":{\"nested\":{\"KeyChain\":{\"fields\":{\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"message\":{\"rule\":\"required\",\"type\":\"SignedMessage\",\"id\":2,\"comment\":null},\"parents\":{\"rule\":\"repeated\",\"type\":\"KeyChain\",\"id\":3,\"comment\":null}},\"comment\":null},\"KeyRecord\":{\"fields\":{\"type\":{\"rule\":\"required\",\"type\":\"KeyType\",\"id\":1,\"comment\":\"The `KeyType` type of the key. This is often unknown for keys from other sources.\"},\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":2,\"comment\":\"The public key as a Buffer (required).\"},\"secretKey\":{\"type\":\"PrivKey\",\"id\":3,\"comment\":\"The secret key as a Buffer (this will never be visible outside the Keyring).\"},\"hint\":{\"type\":\"bool\",\"id\":4,\"comment\":\"Is this key from a Greeting \\\"hint\\\"?\"},\"own\":{\"type\":\"bool\",\"id\":5,\"comment\":\"Determines if this is our key?\\nUsually true if `secretKey` is present; may be false for \\\"inception keys\\\" such as the Party key.\"},\"trusted\":{\"type\":\"bool\",\"id\":6,\"comment\":\"Is this key to be trusted?\"},\"added\":{\"type\":\"string\",\"id\":7,\"comment\":\"An RFC-3339 date/time string for when the key was added to the Keyring.\"},\"created\":{\"type\":\"string\",\"id\":8,\"comment\":\"An RFC-3339 date/time string for when the key was created.\"}},\"comment\":null},\"KeyRecordList\":{\"fields\":{\"keys\":{\"rule\":\"repeated\",\"type\":\"KeyRecord\",\"id\":1,\"comment\":null}},\"comment\":null},\"KeyType\":{\"values\":{\"UNKNOWN\":0,\"IDENTITY\":1,\"DEVICE\":2,\"PARTY\":3,\"FEED\":4,\"DXNS_ADDRESS\":5},\"comment\":null,\"comments\":{\"UNKNOWN\":null,\"IDENTITY\":null,\"DEVICE\":null,\"PARTY\":null,\"FEED\":null,\"DXNS_ADDRESS\":null}},\"PrivKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null},\"PubKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null}}}}},\"mesh\":{\"nested\":{\"signal\":{\"nested\":{\"Acknowledgement\":{\"fields\":{\"messageId\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null}},\"comment\":null},\"Answer\":{\"fields\":{\"accept\":{\"type\":\"bool\",\"id\":1,\"comment\":null},\"offerMessageId\":{\"type\":\"PubKey\",\"id\":2,\"comment\":\"MessageId of the Offer being answered.\"}},\"comment\":null},\"Message\":{\"fields\":{\"id\":{\"type\":\"PubKey\",\"id\":1,\"comment\":\"Sender's public key.\"},\"remoteId\":{\"type\":\"PubKey\",\"id\":2,\"comment\":\"Receiver`s public key.\"},\"topic\":{\"type\":\"PubKey\",\"id\":3,\"comment\":\"Swarm identefier.\"},\"sessionId\":{\"type\":\"PubKey\",\"id\":4,\"comment\":\"Unique connection identifier.\"},\"data\":{\"type\":\"MessageData\",\"id\":5,\"comment\":\"Message payload.\"},\"messageId\":{\"type\":\"PubKey\",\"id\":6,\"comment\":\"Unique message identifier. Used for Acknolegment and matching Anwers to Offers.\"}},\"comment\":null},\"MessageData\":{\"oneofs\":{\"payload\":{\"oneof\":[\"offer\",\"answer\",\"signal\",\"ack\"],\"comment\":null}},\"fields\":{\"offer\":{\"type\":\"Offer\",\"id\":1,\"comment\":null},\"answer\":{\"type\":\"Answer\",\"id\":2,\"comment\":null},\"signal\":{\"type\":\"Signal\",\"id\":3,\"comment\":null},\"ack\":{\"type\":\"Acknowledgement\",\"id\":4,\"comment\":null}},\"comment\":null},\"Offer\":{\"fields\":{},\"comment\":null},\"Signal\":{\"fields\":{\"json\":{\"type\":\"string\",\"id\":1,\"comment\":null}},\"comment\":null}}}}}}},\"google\":{\"nested\":{\"protobuf\":{\"nested\":{\"Any\":{\"fields\":{\"type_url\":{\"type\":\"string\",\"id\":1},\"value\":{\"type\":\"bytes\",\"id\":2}},\"comment\":null}}}}}}}");
40
+ export const schemaJson = JSON.parse("{\"nested\":{\"dxos\":{\"nested\":{\"credentials\":{\"nested\":{\"Message\":{\"fields\":{\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":1,\"comment\":null}},\"comment\":null},\"SignedMessage\":{\"fields\":{\"signed\":{\"rule\":\"required\",\"type\":\"Signed\",\"id\":1,\"comment\":\"The signed message contents.\"},\"signatures\":{\"rule\":\"repeated\",\"type\":\"Signature\",\"id\":2,\"comment\":\"An array of Signatures, one for each key that signed the message.\"}},\"nested\":{\"Signature\":{\"oneofs\":{\"_keyChain\":{\"oneof\":[\"keyChain\"]}},\"fields\":{\"key\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":\"The publicKey of the keypair that made this signature.\"},\"signature\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":\"The bytes of the signature.\"},\"keyChain\":{\"type\":\"KeyChain\",\"id\":3,\"options\":{\"proto3_optional\":true},\"comment\":\"The certification chain of SignedMessages for this key.\"}},\"comment\":null},\"Signed\":{\"fields\":{\"created\":{\"rule\":\"required\",\"type\":\"string\",\"id\":1,\"comment\":\"RFC-3339 datetime string.\"},\"nonce\":{\"rule\":\"required\",\"type\":\"bytes\",\"id\":2,\"comment\":null},\"payload\":{\"rule\":\"required\",\"type\":\"google.protobuf.Any\",\"id\":10,\"comment\":\"The payload to be signed.\"}},\"comment\":null}},\"comment\":\"A generic container message used whenever messages are signed (e.g. PartyCredential)\"}}},\"halo\":{\"nested\":{\"keys\":{\"nested\":{\"KeyChain\":{\"fields\":{\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":1,\"comment\":null},\"message\":{\"rule\":\"required\",\"type\":\"SignedMessage\",\"id\":2,\"comment\":null},\"parents\":{\"rule\":\"repeated\",\"type\":\"KeyChain\",\"id\":3,\"comment\":null}},\"comment\":null},\"KeyRecord\":{\"oneofs\":{\"_secretKey\":{\"oneof\":[\"secretKey\"]},\"_hint\":{\"oneof\":[\"hint\"]},\"_own\":{\"oneof\":[\"own\"]},\"_trusted\":{\"oneof\":[\"trusted\"]},\"_added\":{\"oneof\":[\"added\"]},\"_created\":{\"oneof\":[\"created\"]}},\"fields\":{\"type\":{\"rule\":\"required\",\"type\":\"KeyType\",\"id\":1,\"comment\":\"The `KeyType` type of the key. This is often unknown for keys from other sources.\"},\"publicKey\":{\"rule\":\"required\",\"type\":\"PubKey\",\"id\":2,\"comment\":\"The public key as a Buffer (required).\"},\"secretKey\":{\"type\":\"PrivKey\",\"id\":3,\"options\":{\"proto3_optional\":true},\"comment\":\"The secret key as a Buffer (this will never be visible outside the Keyring).\"},\"hint\":{\"type\":\"bool\",\"id\":4,\"options\":{\"proto3_optional\":true},\"comment\":\"Is this key from a Greeting \\\"hint\\\"?\"},\"own\":{\"type\":\"bool\",\"id\":5,\"options\":{\"proto3_optional\":true},\"comment\":\"Determines if this is our key?\\nUsually true if `secretKey` is present; may be false for \\\"inception keys\\\" such as the Party key.\"},\"trusted\":{\"type\":\"bool\",\"id\":6,\"options\":{\"proto3_optional\":true},\"comment\":\"Is this key to be trusted?\"},\"added\":{\"type\":\"string\",\"id\":7,\"options\":{\"proto3_optional\":true},\"comment\":\"An RFC-3339 date/time string for when the key was added to the Keyring.\"},\"created\":{\"type\":\"string\",\"id\":8,\"options\":{\"proto3_optional\":true},\"comment\":\"An RFC-3339 date/time string for when the key was created.\"}},\"comment\":null},\"KeyRecordList\":{\"fields\":{\"keys\":{\"rule\":\"repeated\",\"type\":\"KeyRecord\",\"id\":1,\"comment\":null}},\"comment\":null},\"KeyType\":{\"values\":{\"UNKNOWN\":0,\"IDENTITY\":1,\"DEVICE\":2,\"PARTY\":3,\"FEED\":4,\"DXNS_ADDRESS\":5},\"comment\":null,\"comments\":{\"UNKNOWN\":null,\"IDENTITY\":null,\"DEVICE\":null,\"PARTY\":null,\"FEED\":null,\"DXNS_ADDRESS\":null}},\"PrivKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null},\"PubKey\":{\"fields\":{\"data\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null}}}}},\"mesh\":{\"nested\":{\"signal\":{\"options\":{\"go_package\":\"github.com/dxos/kube/go/signal/pb\"},\"nested\":{\"HostEvent\":{\"oneofs\":{\"event\":{\"oneof\":[\"peerAvailable\"],\"comment\":null}},\"fields\":{\"peerAvailable\":{\"type\":\"SwarmEvent.PeerAvailable\",\"id\":1,\"comment\":null}},\"comment\":null},\"JoinRequest\":{\"fields\":{\"swarm\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"peer\":{\"type\":\"bytes\",\"id\":2,\"comment\":null}},\"comment\":null},\"Message\":{\"fields\":{\"author\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"recipient\":{\"type\":\"bytes\",\"id\":2,\"comment\":null},\"payload\":{\"type\":\"google.protobuf.Any\",\"id\":3,\"comment\":null}},\"comment\":null},\"PeerEvent\":{\"oneofs\":{\"event\":{\"oneof\":[\"message\"],\"comment\":null}},\"fields\":{\"message\":{\"type\":\"Message\",\"id\":1,\"comment\":null}},\"comment\":null},\"ReceptionRequest\":{\"fields\":{\"peer\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null},\"Signal\":{\"methods\":{\"Join\":{\"requestType\":\"JoinRequest\",\"responseType\":\"SwarmEvent\",\"responseStream\":true,\"comment\":null},\"ReceiveMessages\":{\"requestType\":\"ReceptionRequest\",\"responseType\":\"Message\",\"responseStream\":true,\"comment\":null},\"SendMessage\":{\"requestType\":\"Message\",\"responseType\":\"google.protobuf.Empty\",\"comment\":null}},\"comment\":null},\"SwarmEvent\":{\"oneofs\":{\"event\":{\"oneof\":[\"peerAvailable\",\"peerLeft\"],\"comment\":null}},\"fields\":{\"peerAvailable\":{\"type\":\"PeerAvailable\",\"id\":1,\"comment\":null},\"peerLeft\":{\"type\":\"PeerLeft\",\"id\":2,\"comment\":null}},\"nested\":{\"PeerAvailable\":{\"oneofs\":{\"_until\":{\"oneof\":[\"until\"]},\"_announceBackToHost\":{\"oneof\":[\"announceBackToHost\"]}},\"fields\":{\"peer\":{\"type\":\"bytes\",\"id\":1,\"comment\":null},\"since\":{\"type\":\"google.protobuf.Timestamp\",\"id\":2,\"comment\":null},\"until\":{\"type\":\"google.protobuf.Timestamp\",\"id\":3,\"options\":{\"proto3_optional\":true},\"comment\":null},\"announceBackToHost\":{\"type\":\"bytes\",\"id\":4,\"options\":{\"proto3_optional\":true},\"comment\":null}},\"comment\":null},\"PeerLeft\":{\"fields\":{\"peer\":{\"type\":\"bytes\",\"id\":1,\"comment\":null}},\"comment\":null}},\"comment\":null}}},\"signalMessage\":{\"nested\":{\"Acknowledgement\":{\"fields\":{\"messageId\":{\"type\":\"PubKey\",\"id\":1,\"comment\":null}},\"comment\":null},\"Answer\":{\"oneofs\":{\"_offerMessageId\":{\"oneof\":[\"offerMessageId\"]}},\"fields\":{\"accept\":{\"type\":\"bool\",\"id\":1,\"comment\":null},\"offerMessageId\":{\"type\":\"PubKey\",\"id\":2,\"options\":{\"proto3_optional\":true},\"comment\":\"MessageId of the Offer being answered.\"}},\"comment\":null},\"MessageData\":{\"oneofs\":{\"payload\":{\"oneof\":[\"offer\",\"answer\",\"signal\",\"ack\"],\"comment\":null}},\"fields\":{\"offer\":{\"type\":\"Offer\",\"id\":1,\"comment\":null},\"answer\":{\"type\":\"Answer\",\"id\":2,\"comment\":null},\"signal\":{\"type\":\"Signal\",\"id\":3,\"comment\":null},\"ack\":{\"type\":\"Acknowledgement\",\"id\":4,\"comment\":null}},\"comment\":null},\"Offer\":{\"fields\":{},\"comment\":null},\"Signal\":{\"fields\":{\"json\":{\"type\":\"string\",\"id\":1,\"comment\":null}},\"comment\":null},\"SignalMessage\":{\"oneofs\":{\"_messageId\":{\"oneof\":[\"messageId\"]}},\"fields\":{\"id\":{\"type\":\"PubKey\",\"id\":1,\"comment\":\"Sender's public key.\"},\"remoteId\":{\"type\":\"PubKey\",\"id\":2,\"comment\":\"Receiver`s public key.\"},\"topic\":{\"type\":\"PubKey\",\"id\":3,\"comment\":\"Swarm identefier.\"},\"sessionId\":{\"type\":\"PubKey\",\"id\":4,\"comment\":\"Unique connection identifier.\"},\"data\":{\"type\":\"MessageData\",\"id\":5,\"comment\":\"Message payload.\"},\"messageId\":{\"type\":\"PubKey\",\"id\":6,\"options\":{\"proto3_optional\":true},\"comment\":\"Unique message identifier. Used for Acknolegment and matching Anwers to Offers.\"}},\"comment\":null}}}}}}},\"google\":{\"nested\":{\"protobuf\":{\"nested\":{\"Any\":{\"fields\":{\"type_url\":{\"type\":\"string\",\"id\":1},\"value\":{\"type\":\"bytes\",\"id\":2}},\"comment\":null},\"Empty\":{\"fields\":{},\"comment\":null},\"Timestamp\":{\"fields\":{\"seconds\":{\"type\":\"int64\",\"id\":1},\"nanos\":{\"type\":\"int32\",\"id\":2}},\"comment\":null}}}}}}}");
29
41
  export const schema = Schema.fromJson<TYPES, SERVICES>(schemaJson, substitutions);
@@ -2,8 +2,10 @@
2
2
  // Copyright 2021 DXOS.org
3
3
  //
4
4
 
5
+ import { timestampSubstitutions } from '@dxos/codec-protobuf';
5
6
  import { publicKeySubstitutions } from '@dxos/protocols';
6
7
 
7
8
  export default {
8
- ...publicKeySubstitutions
9
+ ...publicKeySubstitutions,
10
+ ...timestampSubstitutions
9
11
  };
@@ -8,19 +8,22 @@ import { Event } from '@dxos/async';
8
8
  import { PublicKey } from '@dxos/protocols';
9
9
  import { ComplexMap, ComplexSet } from '@dxos/util';
10
10
 
11
- import { Answer, Message } from '../proto/gen/dxos/mesh/signal';
11
+ import { SwarmEvent } from '../proto/gen/dxos/mesh/signal';
12
+ import { Answer, SignalMessage } from '../proto/gen/dxos/mesh/signalMessage';
12
13
  import { SignalApi } from './signal-api';
13
14
  import { SignalManager } from './signal-manager';
14
15
 
15
16
  export class InMemorySignalManager implements SignalManager {
16
17
  readonly statusChanged = new Event<SignalApi.Status[]>();
17
18
  readonly commandTrace = new Event<SignalApi.CommandTrace>();
18
- readonly peerCandidatesChanged = new Event<[topic: PublicKey, candidates: PublicKey[]]>()
19
- readonly onSignal = new Event<Message>();
19
+ readonly swarmEvent = new Event<[topic: PublicKey, swarmEvent: SwarmEvent]>();
20
+ readonly onMessage = new Event<SignalMessage>();
20
21
 
21
22
  constructor (
22
- private readonly _onOffer: (message: Message) => Promise<Answer>
23
- ) {}
23
+ private readonly _onOffer: (message: SignalMessage) => Promise<Answer>
24
+ ) {
25
+ state.swarmEvent.on(data => this.swarmEvent.emit(data));
26
+ }
24
27
 
25
28
  getStatus (): SignalApi.Status[] {
26
29
  return [];
@@ -34,7 +37,24 @@ export class InMemorySignalManager implements SignalManager {
34
37
  state.swarms.get(topic)!.add(peerId);
35
38
  state.connections.set(peerId, this);
36
39
 
37
- setTimeout(() => this.peerCandidatesChanged.emit([topic, Array.from(state.swarms.get(topic)!.values())]), 0);
40
+ state.swarmEvent.emit([topic, {
41
+ peerAvailable: {
42
+ peer: peerId.asUint8Array(),
43
+ since: new Date()
44
+ }
45
+ }]);
46
+
47
+ // Emitting swarm events for each peer.
48
+ for (const [topic, peerIds] of state.swarms) {
49
+ Array.from(peerIds).forEach(peerId => {
50
+ this.swarmEvent.emit([topic, {
51
+ peerAvailable: {
52
+ peer: peerId.asUint8Array(),
53
+ since: new Date()
54
+ }
55
+ }]);
56
+ });
57
+ }
38
58
  }
39
59
 
40
60
  leave (topic: PublicKey, peerId: PublicKey) {
@@ -43,22 +63,26 @@ export class InMemorySignalManager implements SignalManager {
43
63
  }
44
64
 
45
65
  state.swarms.get(topic)!.delete(peerId);
46
- }
47
66
 
48
- lookup (topic: PublicKey) {
49
- setTimeout(() => this.peerCandidatesChanged.emit([topic, Array.from(state.swarms.get(topic)!.values())]), 0);
67
+ const swarmEvent: SwarmEvent = {
68
+ peerLeft: {
69
+ peer: peerId.asUint8Array()
70
+ }
71
+ };
72
+
73
+ state.swarmEvent.emit([topic, swarmEvent]);
50
74
  }
51
75
 
52
- offer (msg: Message) {
76
+ offer (msg: SignalMessage) {
53
77
  assert(msg.remoteId);
54
78
  assert(state.connections.has(msg.remoteId), 'Peer not connected');
55
79
  return state.connections.get(msg.remoteId)!._onOffer(msg);
56
80
  }
57
81
 
58
- async signal (msg: Message) {
82
+ async message (msg: SignalMessage) {
59
83
  assert(msg.remoteId);
60
84
  assert(state.connections.get(msg.remoteId), 'Peer not connected');
61
- state.connections.get(msg.remoteId)!.onSignal.emit(msg);
85
+ state.connections.get(msg.remoteId)!.onMessage.emit(msg);
62
86
  }
63
87
 
64
88
  async destroy () {}
@@ -67,6 +91,7 @@ export class InMemorySignalManager implements SignalManager {
67
91
  // TODO(burdon): Remove global singleton.
68
92
  // This is global state for the in-memory signal manager.
69
93
  const state = {
94
+ swarmEvent: new Event<[topic: PublicKey, swarmEvent: SwarmEvent]>(),
70
95
  // Mapping from topic to set of peers.
71
96
  swarms: new ComplexMap<PublicKey, ComplexSet<PublicKey>>(x => x.toHex()),
72
97
 
@@ -6,5 +6,4 @@ export * from './in-memory-signal-manager';
6
6
  export * from './signal-api';
7
7
  export * from './signal-client';
8
8
  export * from './signal-manager';
9
- export * from './websocket-rpc';
10
- export * from './websocket-signal-manager';
9
+ export * from './signal-manager-impl';
@@ -0,0 +1,117 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import { expect, mockFn } from 'earljs';
6
+ import waitForExpect from 'wait-for-expect';
7
+
8
+ import { PublicKey } from '@dxos/protocols';
9
+ import { createTestBroker, TestBroker } from '@dxos/signal';
10
+ import { afterTest } from '@dxos/testutils';
11
+
12
+ import { SignalMessage } from '../proto/gen/dxos/mesh/signalMessage';
13
+ import { MessageRouter } from './message-router';
14
+ import { SignalManagerImpl } from './signal-manager-impl';
15
+
16
+ describe('Signal Integration Test', () => {
17
+ let broker: TestBroker;
18
+
19
+ before(async () => {
20
+ broker = await createTestBroker();
21
+ });
22
+
23
+ after(() => {
24
+ broker.stop();
25
+ });
26
+
27
+ const setup = () => {
28
+ const signalManager = new SignalManagerImpl([broker.url()]);
29
+ signalManager.onMessage.on(msg => messageRouter.receiveMessage(msg));
30
+
31
+ const signalMock = mockFn<(msg: SignalMessage) => Promise<void>>().resolvesTo();
32
+ const messageRouter = new MessageRouter({
33
+ sendMessage: msg => signalManager.message(msg),
34
+ onSignal: signalMock,
35
+ onOffer: async () => ({ accept: true })
36
+ });
37
+ afterTest(() => messageRouter.destroy());
38
+
39
+ return {
40
+ signalManager,
41
+ signalMock,
42
+ messageRouter
43
+ };
44
+ };
45
+
46
+ it('two peers connecting', async () => {
47
+ const peerNetworking1 = setup();
48
+ const peerNetworking2 = setup();
49
+
50
+ const peer1 = PublicKey.random();
51
+ const peer2 = PublicKey.random();
52
+ const topic = PublicKey.random();
53
+
54
+ const promise1 = peerNetworking1.signalManager.swarmEvent.waitFor(([, swarmEvent]) => !!swarmEvent.peerAvailable && peer2.equals(swarmEvent.peerAvailable.peer));
55
+ const promise2 = peerNetworking1.signalManager.swarmEvent.waitFor(([, swarmEvent]) => !!swarmEvent.peerAvailable && peer1.equals(swarmEvent.peerAvailable.peer));
56
+
57
+ peerNetworking1.signalManager.join(topic, peer1);
58
+ peerNetworking2.signalManager.join(topic, peer2);
59
+
60
+ await promise1;
61
+ await promise2;
62
+
63
+ expect(await peerNetworking1.messageRouter.offer({
64
+ topic,
65
+ id: peer1,
66
+ remoteId: peer2,
67
+ sessionId: PublicKey.random(),
68
+ data: {
69
+ offer: {}
70
+ }
71
+ })).toBeAnObjectWith({ accept: true });
72
+
73
+ expect(await peerNetworking2.messageRouter.offer({
74
+ topic,
75
+ id: peer2,
76
+ remoteId: peer1,
77
+ sessionId: PublicKey.random(),
78
+ data: {
79
+ offer: {}
80
+ }
81
+ })).toBeAnObjectWith({ accept: true });
82
+
83
+ {
84
+ const message: SignalMessage = {
85
+ topic,
86
+ id: peer1,
87
+ remoteId: peer2,
88
+ sessionId: PublicKey.random(),
89
+ data: {
90
+ signal: { json: JSON.stringify({ 'foo': 'bar' }) }
91
+ }
92
+ };
93
+ await peerNetworking1.messageRouter.signal(message);
94
+
95
+ await waitForExpect(() => {
96
+ expect(peerNetworking2.signalMock).toHaveBeenCalledWith([message]);
97
+ });
98
+ }
99
+
100
+ {
101
+ const message: SignalMessage = {
102
+ topic,
103
+ id: peer2,
104
+ remoteId: peer1,
105
+ sessionId: PublicKey.random(),
106
+ data: {
107
+ signal: { json: JSON.stringify({ 'foo': 'bar' }) }
108
+ }
109
+ };
110
+ await peerNetworking2.messageRouter.signal(message);
111
+
112
+ await waitForExpect(() => {
113
+ expect(peerNetworking1.signalMock).toHaveBeenCalledWith([message]);
114
+ });
115
+ }
116
+ });
117
+ });