@dxos/network-manager 0.1.13 → 0.1.16

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 (256) hide show
  1. package/dist/lib/browser/index.mjs +2127 -0
  2. package/dist/lib/browser/index.mjs.map +7 -0
  3. package/dist/lib/browser/meta.json +1 -0
  4. package/dist/lib/browser/testing/index.mjs +2197 -0
  5. package/dist/lib/browser/testing/index.mjs.map +7 -0
  6. package/dist/lib/node/index.cjs +2173 -0
  7. package/dist/lib/node/index.cjs.map +7 -0
  8. package/dist/lib/node/meta.json +1 -0
  9. package/dist/lib/node/testing/index.cjs +2225 -0
  10. package/dist/lib/node/testing/index.cjs.map +7 -0
  11. package/dist/{src → types/src}/connection-log.d.ts +0 -0
  12. package/dist/types/src/connection-log.d.ts.map +1 -0
  13. package/dist/{src → types/src}/index.d.ts +1 -0
  14. package/dist/types/src/index.d.ts.map +1 -0
  15. package/dist/{src → types/src}/network-manager.d.ts +9 -11
  16. package/dist/types/src/network-manager.d.ts.map +1 -0
  17. package/dist/{src → types/src}/protocol-factory.d.ts +11 -5
  18. package/dist/types/src/protocol-factory.d.ts.map +1 -0
  19. package/dist/{src → types/src}/signal/index.d.ts +0 -0
  20. package/dist/types/src/signal/index.d.ts.map +1 -0
  21. package/dist/{src → types/src}/signal/integration.test.d.ts +0 -0
  22. package/dist/types/src/signal/integration.test.d.ts.map +1 -0
  23. package/dist/{src → types/src}/signal/message-router.d.ts +0 -0
  24. package/dist/types/src/signal/message-router.d.ts.map +1 -0
  25. package/dist/{src → types/src}/signal/message-router.test.d.ts +0 -0
  26. package/dist/types/src/signal/message-router.test.d.ts.map +1 -0
  27. package/dist/{src → types/src}/signal/signal-connection.d.ts +0 -0
  28. package/dist/types/src/signal/signal-connection.d.ts.map +1 -0
  29. package/dist/{src → types/src}/signal/signal-messenger.d.ts +0 -0
  30. package/dist/types/src/signal/signal-messenger.d.ts.map +1 -0
  31. package/dist/{src → types/src}/swarm/connection.d.ts +5 -17
  32. package/dist/types/src/swarm/connection.d.ts.map +1 -0
  33. package/dist/{src → types/src}/swarm/index.d.ts +0 -0
  34. package/dist/types/src/swarm/index.d.ts.map +1 -0
  35. package/dist/types/src/swarm/peer.d.ts +70 -0
  36. package/dist/types/src/swarm/peer.d.ts.map +1 -0
  37. package/dist/{src → types/src}/swarm/swarm-mapper.d.ts +1 -1
  38. package/dist/types/src/swarm/swarm-mapper.d.ts.map +1 -0
  39. package/dist/{src → types/src}/swarm/swarm.d.ts +4 -8
  40. package/dist/types/src/swarm/swarm.d.ts.map +1 -0
  41. package/dist/{src → types/src}/swarm/swarm.test.d.ts +0 -0
  42. package/dist/types/src/swarm/swarm.test.d.ts.map +1 -0
  43. package/dist/{src → types/src}/testing/index.d.ts +0 -0
  44. package/dist/types/src/testing/index.d.ts.map +1 -0
  45. package/dist/{src → types/src}/testing/test-builder.d.ts +1 -1
  46. package/dist/types/src/testing/test-builder.d.ts.map +1 -0
  47. package/dist/{src → types/src}/testing/test-protocol.d.ts +2 -2
  48. package/dist/types/src/testing/test-protocol.d.ts.map +1 -0
  49. package/dist/{src → types/src}/tests/basic-test-suite.d.ts +0 -0
  50. package/dist/types/src/tests/basic-test-suite.d.ts.map +1 -0
  51. package/dist/{src → types/src}/tests/memory-transport.test.d.ts +0 -0
  52. package/dist/types/src/tests/memory-transport.test.d.ts.map +1 -0
  53. package/dist/{src → types/src}/tests/presence.test.d.ts +0 -0
  54. package/dist/types/src/tests/presence.test.d.ts.map +1 -0
  55. package/dist/{src → types/src}/tests/property-test-suite.d.ts +0 -0
  56. package/dist/types/src/tests/property-test-suite.d.ts.map +1 -0
  57. package/dist/{src → types/src}/tests/utils.d.ts +0 -0
  58. package/dist/types/src/tests/utils.d.ts.map +1 -0
  59. package/dist/{src → types/src}/tests/webrtc-transport.test.d.ts +0 -0
  60. package/dist/types/src/tests/webrtc-transport.test.d.ts.map +1 -0
  61. package/dist/{src → types/src}/topology/fully-connected-topology.d.ts +0 -0
  62. package/dist/types/src/topology/fully-connected-topology.d.ts.map +1 -0
  63. package/dist/{src → types/src}/topology/index.d.ts +0 -0
  64. package/dist/types/src/topology/index.d.ts.map +1 -0
  65. package/dist/{src → types/src}/topology/mmst-topology.d.ts +0 -0
  66. package/dist/types/src/topology/mmst-topology.d.ts.map +1 -0
  67. package/dist/{src → types/src}/topology/star-topology.d.ts +0 -0
  68. package/dist/types/src/topology/star-topology.d.ts.map +1 -0
  69. package/dist/{src → types/src}/topology/topology.d.ts +0 -0
  70. package/dist/types/src/topology/topology.d.ts.map +1 -0
  71. package/dist/{src → types/src}/transport/index.d.ts +0 -0
  72. package/dist/types/src/transport/index.d.ts.map +1 -0
  73. package/dist/{src → types/src}/transport/memory-transport.d.ts +0 -0
  74. package/dist/types/src/transport/memory-transport.d.ts.map +1 -0
  75. package/dist/{src → types/src}/transport/memory-transport.test.d.ts +0 -0
  76. package/dist/types/src/transport/memory-transport.test.d.ts.map +1 -0
  77. package/dist/{src → types/src}/transport/transport.d.ts +1 -1
  78. package/dist/types/src/transport/transport.d.ts.map +1 -0
  79. package/dist/{src → types/src}/transport/webrtc-simple-peer.test.d.ts +0 -0
  80. package/dist/types/src/transport/webrtc-simple-peer.test.d.ts.map +1 -0
  81. package/dist/{src → types/src}/transport/webrtc-transport-proxy.d.ts +1 -1
  82. package/dist/types/src/transport/webrtc-transport-proxy.d.ts.map +1 -0
  83. package/dist/{src → types/src}/transport/webrtc-transport-proxy.test.d.ts +0 -0
  84. package/dist/types/src/transport/webrtc-transport-proxy.test.d.ts.map +1 -0
  85. package/dist/{src → types/src}/transport/webrtc-transport-service.d.ts +0 -0
  86. package/dist/types/src/transport/webrtc-transport-service.d.ts.map +1 -0
  87. package/dist/{src → types/src}/transport/webrtc-transport.d.ts +1 -1
  88. package/dist/types/src/transport/webrtc-transport.d.ts.map +1 -0
  89. package/dist/{src → types/src}/transport/webrtc-transport.test.d.ts +0 -0
  90. package/dist/types/src/transport/webrtc-transport.test.d.ts.map +1 -0
  91. package/dist/{src → types/src}/transport/webrtc.d.ts +0 -0
  92. package/dist/types/src/transport/webrtc.d.ts.map +1 -0
  93. package/dist/types/src/types.d.ts +6 -0
  94. package/dist/types/src/types.d.ts.map +1 -0
  95. package/dist/types/src/wire-protocol.d.ts +37 -0
  96. package/dist/types/src/wire-protocol.d.ts.map +1 -0
  97. package/package.json +24 -22
  98. package/src/connection-log.ts +8 -8
  99. package/src/globals.d.ts +1 -1
  100. package/src/index.ts +1 -0
  101. package/src/network-manager.ts +14 -5
  102. package/src/protocol-factory.ts +7 -4
  103. package/src/signal/integration.test.ts +8 -7
  104. package/src/signal/message-router.test.ts +14 -15
  105. package/src/signal/message-router.ts +1 -1
  106. package/src/swarm/connection.ts +11 -55
  107. package/src/swarm/peer.ts +119 -30
  108. package/src/swarm/swarm.test.ts +9 -8
  109. package/src/swarm/swarm.ts +97 -116
  110. package/src/testing/test-builder.ts +4 -1
  111. package/src/testing/test-protocol.ts +1 -1
  112. package/src/tests/basic-test-suite.ts +7 -6
  113. package/src/tests/memory-transport.test.ts +1 -1
  114. package/src/tests/presence.test.ts +5 -4
  115. package/src/tests/property-test-suite.ts +4 -3
  116. package/src/tests/utils.ts +1 -1
  117. package/src/tests/webrtc-transport.test.ts +2 -2
  118. package/src/transport/memory-transport.test.ts +4 -4
  119. package/src/transport/memory-transport.ts +5 -5
  120. package/src/transport/webrtc-simple-peer.test.ts +13 -10
  121. package/src/transport/webrtc-transport-proxy.test.ts +9 -13
  122. package/src/transport/webrtc-transport-proxy.ts +1 -1
  123. package/src/transport/webrtc-transport-service.ts +2 -2
  124. package/src/transport/webrtc-transport.test.ts +4 -4
  125. package/src/transport/webrtc-transport.ts +3 -3
  126. package/src/wire-protocol.ts +75 -0
  127. package/testing.d.ts +1 -1
  128. package/testing.js +1 -1
  129. package/dist/src/connection-log.d.ts.map +0 -1
  130. package/dist/src/connection-log.js +0 -98
  131. package/dist/src/connection-log.js.map +0 -1
  132. package/dist/src/index.d.ts.map +0 -1
  133. package/dist/src/index.js +0 -28
  134. package/dist/src/index.js.map +0 -1
  135. package/dist/src/network-manager.d.ts.map +0 -1
  136. package/dist/src/network-manager.js +0 -118
  137. package/dist/src/network-manager.js.map +0 -1
  138. package/dist/src/protocol-factory.d.ts.map +0 -1
  139. package/dist/src/protocol-factory.js +0 -66
  140. package/dist/src/protocol-factory.js.map +0 -1
  141. package/dist/src/signal/index.d.ts.map +0 -1
  142. package/dist/src/signal/index.js +0 -23
  143. package/dist/src/signal/index.js.map +0 -1
  144. package/dist/src/signal/integration.test.d.ts.map +0 -1
  145. package/dist/src/signal/integration.test.js +0 -105
  146. package/dist/src/signal/integration.test.js.map +0 -1
  147. package/dist/src/signal/message-router.d.ts.map +0 -1
  148. package/dist/src/signal/message-router.js +0 -135
  149. package/dist/src/signal/message-router.js.map +0 -1
  150. package/dist/src/signal/message-router.test.d.ts.map +0 -1
  151. package/dist/src/signal/message-router.test.js +0 -211
  152. package/dist/src/signal/message-router.test.js.map +0 -1
  153. package/dist/src/signal/signal-connection.d.ts.map +0 -1
  154. package/dist/src/signal/signal-connection.js +0 -6
  155. package/dist/src/signal/signal-connection.js.map +0 -1
  156. package/dist/src/signal/signal-messenger.d.ts.map +0 -1
  157. package/dist/src/signal/signal-messenger.js +0 -6
  158. package/dist/src/signal/signal-messenger.js.map +0 -1
  159. package/dist/src/swarm/connection.d.ts.map +0 -1
  160. package/dist/src/swarm/connection.js +0 -204
  161. package/dist/src/swarm/connection.js.map +0 -1
  162. package/dist/src/swarm/index.d.ts.map +0 -1
  163. package/dist/src/swarm/index.js +0 -23
  164. package/dist/src/swarm/index.js.map +0 -1
  165. package/dist/src/swarm/peer.d.ts +0 -45
  166. package/dist/src/swarm/peer.d.ts.map +0 -1
  167. package/dist/src/swarm/peer.js +0 -113
  168. package/dist/src/swarm/peer.js.map +0 -1
  169. package/dist/src/swarm/swarm-mapper.d.ts.map +0 -1
  170. package/dist/src/swarm/swarm-mapper.js +0 -92
  171. package/dist/src/swarm/swarm-mapper.js.map +0 -1
  172. package/dist/src/swarm/swarm.d.ts.map +0 -1
  173. package/dist/src/swarm/swarm.js +0 -305
  174. package/dist/src/swarm/swarm.js.map +0 -1
  175. package/dist/src/swarm/swarm.test.d.ts.map +0 -1
  176. package/dist/src/swarm/swarm.test.js +0 -135
  177. package/dist/src/swarm/swarm.test.js.map +0 -1
  178. package/dist/src/testing/index.d.ts.map +0 -1
  179. package/dist/src/testing/index.js +0 -22
  180. package/dist/src/testing/index.js.map +0 -1
  181. package/dist/src/testing/test-builder.d.ts.map +0 -1
  182. package/dist/src/testing/test-builder.js +0 -145
  183. package/dist/src/testing/test-builder.js.map +0 -1
  184. package/dist/src/testing/test-protocol.d.ts.map +0 -1
  185. package/dist/src/testing/test-protocol.js +0 -143
  186. package/dist/src/testing/test-protocol.js.map +0 -1
  187. package/dist/src/tests/basic-test-suite.d.ts.map +0 -1
  188. package/dist/src/tests/basic-test-suite.js +0 -142
  189. package/dist/src/tests/basic-test-suite.js.map +0 -1
  190. package/dist/src/tests/memory-transport.test.d.ts.map +0 -1
  191. package/dist/src/tests/memory-transport.test.js +0 -12
  192. package/dist/src/tests/memory-transport.test.js.map +0 -1
  193. package/dist/src/tests/presence.test.d.ts.map +0 -1
  194. package/dist/src/tests/presence.test.js +0 -61
  195. package/dist/src/tests/presence.test.js.map +0 -1
  196. package/dist/src/tests/property-test-suite.d.ts.map +0 -1
  197. package/dist/src/tests/property-test-suite.js +0 -203
  198. package/dist/src/tests/property-test-suite.js.map +0 -1
  199. package/dist/src/tests/utils.d.ts.map +0 -1
  200. package/dist/src/tests/utils.js +0 -76
  201. package/dist/src/tests/utils.js.map +0 -1
  202. package/dist/src/tests/webrtc-transport.test.d.ts.map +0 -1
  203. package/dist/src/tests/webrtc-transport.test.js +0 -16
  204. package/dist/src/tests/webrtc-transport.test.js.map +0 -1
  205. package/dist/src/topology/fully-connected-topology.d.ts.map +0 -1
  206. package/dist/src/topology/fully-connected-topology.js +0 -35
  207. package/dist/src/topology/fully-connected-topology.js.map +0 -1
  208. package/dist/src/topology/index.d.ts.map +0 -1
  209. package/dist/src/topology/index.js +0 -24
  210. package/dist/src/topology/index.js.map +0 -1
  211. package/dist/src/topology/mmst-topology.d.ts.map +0 -1
  212. package/dist/src/topology/mmst-topology.js +0 -73
  213. package/dist/src/topology/mmst-topology.js.map +0 -1
  214. package/dist/src/topology/star-topology.d.ts.map +0 -1
  215. package/dist/src/topology/star-topology.js +0 -60
  216. package/dist/src/topology/star-topology.js.map +0 -1
  217. package/dist/src/topology/topology.d.ts.map +0 -1
  218. package/dist/src/topology/topology.js +0 -6
  219. package/dist/src/topology/topology.js.map +0 -1
  220. package/dist/src/transport/index.d.ts.map +0 -1
  221. package/dist/src/transport/index.js +0 -25
  222. package/dist/src/transport/index.js.map +0 -1
  223. package/dist/src/transport/memory-transport.d.ts.map +0 -1
  224. package/dist/src/transport/memory-transport.js +0 -138
  225. package/dist/src/transport/memory-transport.js.map +0 -1
  226. package/dist/src/transport/memory-transport.test.d.ts.map +0 -1
  227. package/dist/src/transport/memory-transport.test.js +0 -96
  228. package/dist/src/transport/memory-transport.test.js.map +0 -1
  229. package/dist/src/transport/transport.d.ts.map +0 -1
  230. package/dist/src/transport/transport.js +0 -6
  231. package/dist/src/transport/transport.js.map +0 -1
  232. package/dist/src/transport/webrtc-simple-peer.test.d.ts.map +0 -1
  233. package/dist/src/transport/webrtc-simple-peer.test.js +0 -24
  234. package/dist/src/transport/webrtc-simple-peer.test.js.map +0 -1
  235. package/dist/src/transport/webrtc-transport-proxy.d.ts.map +0 -1
  236. package/dist/src/transport/webrtc-transport-proxy.js +0 -139
  237. package/dist/src/transport/webrtc-transport-proxy.js.map +0 -1
  238. package/dist/src/transport/webrtc-transport-proxy.test.d.ts.map +0 -1
  239. package/dist/src/transport/webrtc-transport-proxy.test.js +0 -219
  240. package/dist/src/transport/webrtc-transport-proxy.test.js.map +0 -1
  241. package/dist/src/transport/webrtc-transport-service.d.ts.map +0 -1
  242. package/dist/src/transport/webrtc-transport-service.js +0 -93
  243. package/dist/src/transport/webrtc-transport-service.js.map +0 -1
  244. package/dist/src/transport/webrtc-transport.d.ts.map +0 -1
  245. package/dist/src/transport/webrtc-transport.js +0 -77
  246. package/dist/src/transport/webrtc-transport.js.map +0 -1
  247. package/dist/src/transport/webrtc-transport.test.d.ts.map +0 -1
  248. package/dist/src/transport/webrtc-transport.test.js +0 -91
  249. package/dist/src/transport/webrtc-transport.test.js.map +0 -1
  250. package/dist/src/transport/webrtc.d.ts.map +0 -1
  251. package/dist/src/transport/webrtc.js +0 -17
  252. package/dist/src/transport/webrtc.js.map +0 -1
  253. package/dist/src/types.d.ts +0 -6
  254. package/dist/src/types.d.ts.map +0 -1
  255. package/dist/src/types.js +0 -6
  256. package/dist/src/types.js.map +0 -1
@@ -4,21 +4,21 @@
4
4
 
5
5
  import assert from 'node:assert';
6
6
 
7
- import { Event, sleep } from '@dxos/async';
8
- import { discoveryKey } from '@dxos/crypto';
7
+ import { Event, scheduleTask, sleep } from '@dxos/async';
8
+ import { Context } from '@dxos/context';
9
9
  import { ErrorStream } from '@dxos/debug';
10
10
  import { PublicKey } from '@dxos/keys';
11
- import { log } from '@dxos/log';
11
+ import { log, logInfo } from '@dxos/log';
12
12
  import { Messenger } from '@dxos/messaging';
13
13
  import { SwarmEvent } from '@dxos/protocols/proto/dxos/mesh/signal';
14
14
  import { Answer } from '@dxos/protocols/proto/dxos/mesh/swarm';
15
15
  import { ComplexMap, isNotNullOrUndefined } from '@dxos/util';
16
16
 
17
- import { ProtocolProvider } from '../network-manager';
18
17
  import { MessageRouter, OfferMessage, SignalMessage } from '../signal';
19
18
  import { SwarmController, Topology } from '../topology';
20
19
  import { TransportFactory } from '../transport';
21
20
  import { Topic } from '../types';
21
+ import { WireProtocolProvider } from '../wire-protocol';
22
22
  import { Connection } from './connection';
23
23
  import { Peer } from './peer';
24
24
 
@@ -37,12 +37,13 @@ export class Swarm {
37
37
 
38
38
  private readonly _swarmMessenger: MessageRouter;
39
39
 
40
- private _destroyed = false;
40
+ private _ctx = new Context();
41
41
 
42
42
  /**
43
43
  * Unique id of the swarm, local to the current peer, generated when swarm is joined.
44
44
  */
45
- readonly id = PublicKey.random();
45
+ @logInfo
46
+ readonly instanceId = PublicKey.random();
46
47
 
47
48
  /**
48
49
  * New connection to a peer is started.
@@ -71,12 +72,12 @@ export class Swarm {
71
72
  private readonly _topic: PublicKey,
72
73
  private readonly _ownPeerId: PublicKey,
73
74
  private _topology: Topology,
74
- private readonly _protocolProvider: ProtocolProvider,
75
+ private readonly _protocolProvider: WireProtocolProvider,
75
76
  private readonly _messenger: Messenger,
76
77
  private readonly _transportFactory: TransportFactory,
77
78
  private readonly _label: string | undefined
78
79
  ) {
79
- log('creating swarm', { id: this.id, topic: this._topic, peerId: _ownPeerId });
80
+ log('creating swarm', { peerId: _ownPeerId });
80
81
  _topology.init(this._getSwarmController());
81
82
 
82
83
  this._swarmMessenger = new MessageRouter({
@@ -101,6 +102,7 @@ export class Swarm {
101
102
  .filter(isNotNullOrUndefined);
102
103
  }
103
104
 
105
+ @logInfo
104
106
  get ownPeerId() {
105
107
  return this._ownPeerId;
106
108
  }
@@ -112,16 +114,18 @@ export class Swarm {
112
114
  return this._label;
113
115
  }
114
116
 
117
+ @logInfo
115
118
  get topic(): Topic {
116
119
  return this._topic;
117
120
  }
118
121
 
119
122
  // TODO(burdon): async open?
120
123
  async destroy() {
121
- log('destroying', { id: this.id, topic: this._topic });
122
- this._destroyed = true;
124
+ log('destroying...');
125
+ await this._ctx.dispose();
123
126
  await this._topology.destroy();
124
- await Promise.all(Array.from(this._peers.keys()).map((key) => this._closeConnection(key)));
127
+ await Promise.all(Array.from(this._peers.keys()).map((key) => this._destroyPeer(key)));
128
+ log('destroyed');
125
129
  }
126
130
 
127
131
  async setTopology(topology: Topology) {
@@ -129,8 +133,6 @@ export class Swarm {
129
133
  return;
130
134
  }
131
135
  log('setting topology', {
132
- id: this.id,
133
- topic: this._topic,
134
136
  previous: getClassName(this._topology),
135
137
  topology: getClassName(topology)
136
138
  });
@@ -144,29 +146,43 @@ export class Swarm {
144
146
  private _getOrCreatePeer(peerId: PublicKey): Peer {
145
147
  let peer = this._peers.get(peerId);
146
148
  if (!peer) {
147
- peer = new Peer(peerId, this._topic, this._ownPeerId, {
148
- onConnected: () => {
149
- this.connected.emit(peerId);
150
- },
151
- onDisconnected: async () => {
152
- if (!peer!.advertizing) {
153
- await this._destroyPeer(peer!.id);
149
+ peer = new Peer(
150
+ peerId,
151
+ this._topic,
152
+ this._ownPeerId,
153
+ this._swarmMessenger,
154
+ this._protocolProvider,
155
+ this._transportFactory,
156
+ {
157
+ onInitiated: (connection) => {
158
+ this.connectionAdded.emit(connection);
159
+ },
160
+ onConnected: () => {
161
+ this.connected.emit(peerId);
162
+ },
163
+ onDisconnected: async () => {
164
+ if (!peer!.advertizing) {
165
+ await this._destroyPeer(peer!.id);
166
+ }
167
+
168
+ this.disconnected.emit(peerId);
169
+ this._topology.update();
170
+ },
171
+ onRejected: () => {
172
+ // If the peer rejected our connection remove it from the set of candidates.
173
+ // TODO(dmaretskyi): Set flag instead.
174
+ if (this._peers.has(peerId)) {
175
+ void this._destroyPeer(peerId);
176
+ }
177
+ },
178
+ onAccepted: () => {
179
+ this._topology.update();
180
+ },
181
+ onOffer: (remoteId) => {
182
+ return this._topology.onOffer(remoteId);
154
183
  }
155
-
156
- this.disconnected.emit(peerId);
157
- this._topology.update();
158
- },
159
- onRejected: () => {
160
- // If the peer rejected our connection remove it from the set of candidates.
161
- // TODO(dmaretskyi): Set flag instead.
162
- if (this._peers.has(peerId)) {
163
- void this._destroyPeer(peerId);
164
- }
165
- },
166
- onAccepted: () => {
167
- this._topology.update();
168
184
  }
169
- });
185
+ );
170
186
  this._peers.set(peerId, peer);
171
187
  }
172
188
 
@@ -180,15 +196,15 @@ export class Swarm {
180
196
  }
181
197
 
182
198
  onSwarmEvent(swarmEvent: SwarmEvent) {
183
- log('swarm event', { id: this.id, topic: this._topic, swarmEvent }); // TODO(burdon): Stringify.
184
- if (this._destroyed) {
185
- log.warn('ignored for destroyed swarm', { peerId: this.id, topic: this._topic });
199
+ log('swarm event', { swarmEvent }); // TODO(burdon): Stringify.
200
+ if (this._ctx.disposed) {
201
+ log.warn('ignored for destroyed swarm');
186
202
  return;
187
203
  }
188
204
 
189
205
  if (swarmEvent.peerAvailable) {
190
206
  const peerId = PublicKey.from(swarmEvent.peerAvailable.peer);
191
- log('new peer', { id: this.id, topic: this._topic, peerId });
207
+ log('new peer', { peerId });
192
208
  if (!peerId.equals(this._ownPeerId)) {
193
209
  const peer = this._getOrCreatePeer(peerId);
194
210
  peer.advertizing = true;
@@ -207,69 +223,33 @@ export class Swarm {
207
223
  }
208
224
 
209
225
  async onOffer(message: OfferMessage): Promise<Answer> {
210
- log('offer', { id: this.id, topic: this._topic, message });
211
- if (this._destroyed) {
212
- log.warn('ignored for destroyed swarm', { peerId: this.id, topic: this._topic });
226
+ log('offer', { message });
227
+ if (this._ctx.disposed) {
228
+ log.info('ignored for destroyed swarm');
213
229
  return { accept: false };
214
230
  }
215
231
 
216
232
  // Id of the peer offering us the connection.
217
233
  assert(message.author);
218
- const remoteId = message.author;
219
234
  if (!message.recipient?.equals(this._ownPeerId)) {
220
- log('rejecting offer with incorrect peerId', { id: this.id, topic: this._topic, message });
235
+ log('rejecting offer with incorrect peerId', { message });
221
236
  return { accept: false };
222
237
  }
223
238
  if (!message.topic?.equals(this._topic)) {
224
- log('rejecting offer with incorrect topic', { id: this.id, topic: this._topic, message });
239
+ log('rejecting offer with incorrect topic', { message });
225
240
  return { accept: false };
226
241
  }
227
242
 
228
- const peer = this._getOrCreatePeer(remoteId);
229
-
230
- // Check if we are already trying to connect to that peer.
231
- if (peer.connection) {
232
- // Peer with the highest Id closes its connection, and accepts remote peer's offer.
233
- if (remoteId.toHex() < this._ownPeerId.toHex()) {
234
- log("closing local connection and accepting remote peer's offer", {
235
- id: this.id,
236
- topic: this._topic,
237
- peerId: this._ownPeerId
238
- });
239
- // Close our connection and accept remote peer's connection.
240
- await this._closeConnection(remoteId).catch((err) => {
241
- this.errors.raise(err);
242
- });
243
- } else {
244
- // Continue with our origination attempt, the remote peer will close it's connection and accept ours.
245
- return { accept: true };
246
- }
247
- }
248
-
249
- let accept = false;
250
- if (await this._topology.onOffer(remoteId)) {
251
- if (!peer.connection) {
252
- // Connection might have been already established.
253
- assert(message.sessionId);
254
- const connection = this._createConnection(false, message.author, message.sessionId);
255
- try {
256
- connection.openConnection();
257
- } catch (err: any) {
258
- this.errors.raise(err);
259
- }
260
-
261
- accept = true;
262
- }
263
- }
264
-
243
+ const peer = this._getOrCreatePeer(message.author);
244
+ const answer = await peer.onOffer(message);
265
245
  this._topology.update();
266
- return { accept };
246
+ return answer;
267
247
  }
268
248
 
269
249
  async onSignal(message: SignalMessage): Promise<void> {
270
- log('signal', { id: this.id, topic: this._topic, message });
271
- if (this._destroyed) {
272
- log.warn('ignored for destroyed swarm', { peerId: this.id, topic: this._topic });
250
+ log('signal', { message });
251
+ if (this._ctx.disposed) {
252
+ log.info('ignored for destroyed swarm');
273
253
  return;
274
254
  }
275
255
  assert(
@@ -294,14 +274,30 @@ export class Swarm {
294
274
  .filter((peer) => !peer.connection && peer.advertizing)
295
275
  .map((peer) => peer.id)
296
276
  }),
297
- connect: (peer) => this._initiateConnection(peer),
277
+ connect: (peer) => {
278
+ if (this._ctx.disposed) {
279
+ return;
280
+ }
281
+
282
+ // Run in a separate non-blocking task.
283
+ scheduleTask(this._ctx, async () => {
284
+ try {
285
+ await this._initiateConnection(peer);
286
+ } catch (err: any) {
287
+ log.warn('initiation error', err);
288
+ }
289
+ });
290
+ },
298
291
  disconnect: async (peer) => {
299
- try {
300
- await this._closeConnection(peer);
301
- } catch (err: any) {
302
- this.errors.raise(err);
292
+ if (this._ctx.disposed) {
293
+ return;
303
294
  }
304
- this._topology.update();
295
+
296
+ // Run in a separate non-blocking task.
297
+ scheduleTask(this._ctx, async () => {
298
+ await this._closeConnection(peer);
299
+ this._topology.update();
300
+ });
305
301
  }
306
302
  };
307
303
  }
@@ -313,39 +309,24 @@ export class Swarm {
313
309
  // It is likely that the other peer will also try to connect to us at the same time.
314
310
  // If our peerId is higher, we will wait for a bit so that other peer has a chance to connect first.
315
311
  if (remoteId.toHex() < this._ownPeerId.toHex()) {
312
+ log('initiation delay', { remoteId });
316
313
  await sleep(INITIATION_DELAY);
317
314
  }
318
-
319
- if (this._peers.get(remoteId)?.connection) {
320
- // Do nothing if peer is already connected.
315
+ if (this._ctx.disposed) {
321
316
  return;
322
317
  }
323
318
 
324
- const sessionId = PublicKey.random();
325
-
326
- log('initiating...', { id: this.id, topic: this._topic, peerId: remoteId, sessionId });
327
- const connection = this._createConnection(true, remoteId, sessionId);
328
- connection.initiate();
329
- this._topology.update();
330
- log('initiated', { id: this.id, topic: this._topic });
331
- }
332
-
333
- /**
334
- * Synchronously create a connection, which must be initialized.
335
- */
336
- private _createConnection(initiator: boolean, remoteId: PublicKey, sessionId: PublicKey): Connection {
337
319
  const peer = this._getOrCreatePeer(remoteId);
338
320
 
339
- const connection = peer.createConnection(
340
- this._swarmMessenger,
341
- initiator,
342
- sessionId,
343
- this._protocolProvider({ channel: discoveryKey(this._topic), initiator }),
344
- this._transportFactory
345
- );
321
+ if (peer.connection) {
322
+ // Do nothing if peer is already connected.
323
+ return;
324
+ }
346
325
 
347
- this.connectionAdded.emit(connection);
348
- return connection;
326
+ log('initiating connection...', { remoteId });
327
+ await peer.initiateConnection();
328
+ this._topology.update();
329
+ log('initiated', { remoteId });
349
330
  }
350
331
 
351
332
  private async _closeConnection(peerId: PublicKey) {
@@ -17,6 +17,7 @@ import {
17
17
  WebRTCTransportProxyFactory,
18
18
  WebRTCTransportService
19
19
  } from '../transport';
20
+ import { adaptProtocolProvider } from '../wire-protocol';
20
21
  import { TestProtocolPlugin, testProtocolProvider } from './test-protocol';
21
22
 
22
23
  // Signal server will be started by the setup script.
@@ -165,7 +166,9 @@ export class TestSwarmConnection {
165
166
  await this.peer._networkManager.joinSwarm({
166
167
  topic: this.topic,
167
168
  peerId: this.peer.peerId,
168
- protocol: testProtocolProvider(this.topic.asBuffer(), this.peer.peerId, this.plugin),
169
+ protocolProvider: adaptProtocolProvider(
170
+ testProtocolProvider(this.topic.asBuffer(), this.peer.peerId, this.plugin)
171
+ ),
169
172
  topology
170
173
  });
171
174
 
@@ -4,8 +4,8 @@
4
4
 
5
5
  // Test/mock Protocol implementation used in network-manager tests.
6
6
 
7
- import { EventEmitter } from 'events';
8
7
  import assert from 'node:assert';
8
+ import { EventEmitter } from 'node:events';
9
9
 
10
10
  import { PublicKey } from '@dxos/keys';
11
11
  import { log } from '@dxos/log';
@@ -9,6 +9,7 @@ import { latch } from '@dxos/async';
9
9
  import { PublicKey } from '@dxos/keys';
10
10
  import { log } from '@dxos/log';
11
11
  import { Protocol } from '@dxos/mesh-protocol';
12
+ import { test } from '@dxos/test';
12
13
  import { range } from '@dxos/util';
13
14
 
14
15
  import { TestBuilder } from '../testing';
@@ -25,7 +26,7 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
25
26
  return;
26
27
  }
27
28
 
28
- it('joins swarm, sends messages, and cleanly exits', async () => {
29
+ test('joins swarm, sends messages, and cleanly exits', async () => {
29
30
  const peer1 = testBuilder.createPeer();
30
31
  const peer2 = testBuilder.createPeer();
31
32
  await openAndCloseAfterTest([peer1, peer2]);
@@ -37,7 +38,7 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
37
38
  });
38
39
 
39
40
  // TODO(burdon): Test with more peers (configure and test messaging).
40
- it('joins swarm with star topology', async () => {
41
+ test('joins swarm with star topology', async () => {
41
42
  const peer1 = testBuilder.createPeer();
42
43
  const peer2 = testBuilder.createPeer();
43
44
  await openAndCloseAfterTest([peer1, peer2]);
@@ -49,7 +50,7 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
49
50
  });
50
51
 
51
52
  // TODO(burdon): Fails when trying to reconnect to same topic.
52
- it('joins swarm multiple times', async () => {
53
+ test('joins swarm multiple times', async () => {
53
54
  const peer1 = testBuilder.createPeer();
54
55
  const peer2 = testBuilder.createPeer();
55
56
  await openAndCloseAfterTest([peer1, peer2]);
@@ -75,7 +76,7 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
75
76
  }
76
77
  });
77
78
 
78
- it.skip('joins multiple swarms', async () => {
79
+ test.skip('joins multiple swarms', async () => {
79
80
  // TODO(burdon): N peers.
80
81
  // TODO(burdon): Merge with test below.
81
82
  const peer1 = testBuilder.createPeer();
@@ -90,7 +91,7 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
90
91
  // TODO(burdon): Fails with WebRTC.
91
92
  // TODO(burdon): This just tests multiple swarms (not peers in the same swarm)?
92
93
  // Generalize for n swarms and factor into other tests; configure message activity.
93
- it.skip('joins multiple swarms concurrently', async () => {
94
+ test.skip('joins multiple swarms concurrently', async () => {
94
95
  const createSwarm = async (messages: any[], label: string) => {
95
96
  const topicA = PublicKey.random();
96
97
  const peer1a = testBuilder.createPeer();
@@ -125,7 +126,7 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
125
126
 
126
127
  // TODO(burdon): Fails with WebRTC.
127
128
  // TODO(burdon): Factor out components of test.
128
- it.skip('many peers and connections', async () => {
129
+ test.skip('many peers and connections', async () => {
129
130
  const numTopics = 5;
130
131
  const peersPerTopic = 5;
131
132
 
@@ -5,7 +5,7 @@
5
5
  import { TestBuilder } from '../testing';
6
6
  import { basicTestSuite } from './basic-test-suite';
7
7
 
8
- describe('Memory transport', function () {
8
+ describe('Memory transport', () => {
9
9
  const testBuilder = new TestBuilder();
10
10
  basicTestSuite(testBuilder);
11
11
  });
@@ -8,12 +8,13 @@ import waitForExpect from 'wait-for-expect';
8
8
  import { PublicKey } from '@dxos/keys';
9
9
  import { MemorySignalManagerContext, MemorySignalManager } from '@dxos/messaging';
10
10
  import { PresencePlugin } from '@dxos/protocol-plugin-presence';
11
- import { afterTest } from '@dxos/testutils';
11
+ import { describe, test, afterTest } from '@dxos/test';
12
12
 
13
13
  import { NetworkManager } from '../network-manager';
14
14
  import { createProtocolFactory } from '../protocol-factory';
15
15
  import { FullyConnectedTopology } from '../topology';
16
16
  import { MemoryTransportFactory } from '../transport';
17
+ import { adaptProtocolProvider } from '../wire-protocol';
17
18
 
18
19
  const signalContext = new MemorySignalManagerContext();
19
20
 
@@ -32,7 +33,7 @@ const createPeer = async (topic: PublicKey) => {
32
33
 
33
34
  await networkManager.joinSwarm({
34
35
  peerId,
35
- protocol: createProtocolFactory(topic, peerId, [presencePlugin]),
36
+ protocolProvider: adaptProtocolProvider(createProtocolFactory(topic, peerId, [presencePlugin])),
36
37
  topic,
37
38
  topology: new FullyConnectedTopology()
38
39
  });
@@ -40,8 +41,8 @@ const createPeer = async (topic: PublicKey) => {
40
41
  return { peerId, presence: presencePlugin, networkManager };
41
42
  };
42
43
 
43
- describe('Presence', function () {
44
- it('detects connected peers', async function () {
44
+ describe('Presence', () => {
45
+ test('detects connected peers', async () => {
45
46
  // TODO(burdon): Configure plugins.
46
47
  // const testBuilder = new TestBuilder();
47
48
  // const peer1 = testBuilder.createPeer();
@@ -8,19 +8,20 @@ import waitForExpect from 'wait-for-expect';
8
8
 
9
9
  import { PublicKey } from '@dxos/keys';
10
10
  import { PresencePlugin } from '@dxos/protocol-plugin-presence';
11
- import { afterTest } from '@dxos/testutils';
11
+ import { afterTest, test } from '@dxos/test';
12
12
  import { range, ComplexMap, ComplexSet } from '@dxos/util';
13
13
 
14
14
  import { NetworkManager } from '../network-manager';
15
15
  import { createProtocolFactory } from '../protocol-factory';
16
16
  import { FullyConnectedTopology } from '../topology';
17
+ import { adaptProtocolProvider } from '../wire-protocol';
17
18
 
18
19
  /**
19
20
  * Performs random actions in the real system and compares its state with a simplified model.
20
21
  */
21
22
  // TODO(dmaretskyi): Run this with actual webrtc and signal servers.
22
23
  export const propertyTestSuite = () => {
23
- it.skip('property-based tests', async function () {
24
+ test.skip('property-based tests', async function () {
24
25
  /**
25
26
  * The simplified model of the system.
26
27
  */
@@ -124,7 +125,7 @@ export const propertyTestSuite = () => {
124
125
  await peer.networkManager.joinSwarm({
125
126
  peerId: this.peerId, // TODO(burdon): `this`?
126
127
  topic: model.topic,
127
- protocol,
128
+ protocolProvider: adaptProtocolProvider(protocol),
128
129
  topology: new FullyConnectedTopology(),
129
130
  presence
130
131
  });
@@ -6,7 +6,7 @@ import { expect } from 'chai';
6
6
 
7
7
  import { latch, Trigger } from '@dxos/async';
8
8
  import { PublicKey } from '@dxos/keys';
9
- import { afterTest } from '@dxos/testutils';
9
+ import { afterTest } from '@dxos/test';
10
10
  import { Provider } from '@dxos/util';
11
11
 
12
12
  import { TestPeer, TestSwarmConnection } from '../testing';
@@ -5,12 +5,12 @@
5
5
  import { TEST_SIGNAL_URL, TestBuilder } from '../testing';
6
6
  import { basicTestSuite } from './basic-test-suite';
7
7
 
8
- describe('WebRTC transport', function () {
8
+ describe('WebRTC transport', () => {
9
9
  const testBuilder = new TestBuilder({ signalHosts: [TEST_SIGNAL_URL] });
10
10
  basicTestSuite(testBuilder);
11
11
  }).timeout(10_000);
12
12
 
13
- describe('WebRTC transport proxy', function () {
13
+ describe('WebRTC transport proxy', () => {
14
14
  const testBuilder = new TestBuilder({ signalHosts: [TEST_SIGNAL_URL], bridge: true });
15
15
  basicTestSuite(testBuilder);
16
16
  }).timeout(10_000);
@@ -8,7 +8,7 @@ import waitForExpect from 'wait-for-expect';
8
8
  import { discoveryKey } from '@dxos/crypto';
9
9
  import { PublicKey } from '@dxos/keys';
10
10
  import { Protocol } from '@dxos/mesh-protocol';
11
- import { afterTest } from '@dxos/testutils';
11
+ import { describe, test, afterTest } from '@dxos/test';
12
12
  import { range } from '@dxos/util';
13
13
 
14
14
  import { TestProtocolPlugin, testProtocolProvider } from '../testing';
@@ -61,8 +61,8 @@ const createPair = () => {
61
61
  };
62
62
  };
63
63
 
64
- describe('MemoryTransport', function () {
65
- it('establish connection and send data through with protocol', async function () {
64
+ describe('MemoryTransport', () => {
65
+ test('establish connection and send data through with protocol', async () => {
66
66
  const { plugin1, plugin2, peer1Id } = createPair();
67
67
 
68
68
  const received: any[] = [];
@@ -83,7 +83,7 @@ describe('MemoryTransport', function () {
83
83
  });
84
84
  });
85
85
 
86
- it.skip('10 pairs of peers connecting at the same time', async function () {
86
+ test.skip('10 pairs of peers connecting at the same time', async () => {
87
87
  await Promise.all(
88
88
  range(10).map(async () => {
89
89
  const { plugin1, plugin2, peer1Id } = createPair();
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import assert from 'node:assert';
6
- import { Transform } from 'stream';
6
+ import { Transform } from 'node:stream';
7
7
 
8
8
  import { Event, Trigger } from '@dxos/async';
9
9
  import { ErrorStream } from '@dxos/debug';
@@ -67,7 +67,7 @@ export class MemoryTransport implements Transport {
67
67
  setTimeout(async () => {
68
68
  log('sending signal', { transportId: this._id });
69
69
  void this.options.sendSignal({
70
- json: JSON.stringify({ transportId: this._id.toHex() })
70
+ payload: { transportId: this._id.toHex() }
71
71
  });
72
72
  });
73
73
  } else {
@@ -143,10 +143,10 @@ export class MemoryTransport implements Transport {
143
143
  }
144
144
 
145
145
  signal(signal: Signal) {
146
- const { json } = signal;
147
- if (json) {
146
+ const { payload: json } = signal;
147
+ if (json && json.transportId) {
148
148
  // TODO(burdon): Check open?
149
- const { transportId } = JSON.parse(json);
149
+ const transportId = json.transportId as string;
150
150
  if (transportId) {
151
151
  const remoteId = PublicKey.fromHex(transportId);
152
152
  log('received signal', { id: this._id, remoteId });
@@ -2,23 +2,26 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- // @dxos/mocha platform=nodejs
5
+ // @dxos/test platform=nodejs
6
6
 
7
7
  import wrtc from '@koush/wrtc';
8
8
  import SimplePeerConstructor from 'simple-peer';
9
9
 
10
10
  import { sleep } from '@dxos/async';
11
+ import { describe, test } from '@dxos/test';
11
12
 
12
- describe('Node WebRTC and simple-peer', function () {
13
+ describe('Node WebRTC and simple-peer', () => {
13
14
  // Simplest test that reproduces SIGABRT (mac) and SIGSEGV (linux) in wrtc.
14
- it.skip('open and close', async function () {
15
- const peer = new SimplePeerConstructor({
16
- initiator: true,
17
- wrtc
18
- });
15
+ test
16
+ .skip('open and close', async () => {
17
+ const peer = new SimplePeerConstructor({
18
+ initiator: true,
19
+ wrtc
20
+ });
19
21
 
20
- await sleep(1);
22
+ await sleep(1);
21
23
 
22
- await peer.destroy();
23
- }).timeout(3_000);
24
+ await peer.destroy();
25
+ })
26
+ .timeout(3_000);
24
27
  });