@dxos/network-manager 0.1.2 → 0.1.4

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 (43) hide show
  1. package/dist/src/connection-log.d.ts +1 -1
  2. package/dist/src/connection-log.d.ts.map +1 -1
  3. package/dist/src/network-manager.test.js +10 -13
  4. package/dist/src/network-manager.test.js.map +1 -1
  5. package/dist/src/swarm/connection.d.ts.map +1 -1
  6. package/dist/src/swarm/connection.js +14 -10
  7. package/dist/src/swarm/connection.js.map +1 -1
  8. package/dist/src/transport/memory-transport.d.ts +6 -13
  9. package/dist/src/transport/memory-transport.d.ts.map +1 -1
  10. package/dist/src/transport/memory-transport.js +41 -35
  11. package/dist/src/transport/memory-transport.js.map +1 -1
  12. package/dist/src/transport/memory-transport.test.js +14 -3
  13. package/dist/src/transport/memory-transport.test.js.map +1 -1
  14. package/dist/src/transport/transport.d.ts +1 -7
  15. package/dist/src/transport/transport.d.ts.map +1 -1
  16. package/dist/src/transport/webrtc-transport-proxy.d.ts +3 -9
  17. package/dist/src/transport/webrtc-transport-proxy.d.ts.map +1 -1
  18. package/dist/src/transport/webrtc-transport-proxy.js +12 -17
  19. package/dist/src/transport/webrtc-transport-proxy.js.map +1 -1
  20. package/dist/src/transport/webrtc-transport-proxy.test.js +14 -40
  21. package/dist/src/transport/webrtc-transport-proxy.test.js.map +1 -1
  22. package/dist/src/transport/webrtc-transport-service.d.ts +1 -4
  23. package/dist/src/transport/webrtc-transport-service.d.ts.map +1 -1
  24. package/dist/src/transport/webrtc-transport-service.js +32 -36
  25. package/dist/src/transport/webrtc-transport-service.js.map +1 -1
  26. package/dist/src/transport/webrtc-transport.d.ts +8 -13
  27. package/dist/src/transport/webrtc-transport.d.ts.map +1 -1
  28. package/dist/src/transport/webrtc-transport.js +18 -44
  29. package/dist/src/transport/webrtc-transport.js.map +1 -1
  30. package/dist/src/transport/webrtc-transport.test.js +25 -14
  31. package/dist/src/transport/webrtc-transport.test.js.map +1 -1
  32. package/package.json +16 -16
  33. package/src/connection-log.ts +1 -1
  34. package/src/network-manager.test.ts +0 -3
  35. package/src/swarm/connection.ts +9 -5
  36. package/src/transport/memory-transport.test.ts +14 -15
  37. package/src/transport/memory-transport.ts +48 -49
  38. package/src/transport/transport.ts +1 -9
  39. package/src/transport/webrtc-transport-proxy.test.ts +16 -51
  40. package/src/transport/webrtc-transport-proxy.ts +13 -23
  41. package/src/transport/webrtc-transport-service.ts +34 -39
  42. package/src/transport/webrtc-transport.test.ts +17 -30
  43. package/src/transport/webrtc-transport.ts +22 -54
@@ -3,10 +3,9 @@
3
3
  //
4
4
 
5
5
  import assert from 'assert';
6
- import SimplePeerConstructor, { Instance as SimplePeer } from 'simple-peer';
6
+ import { Duplex } from 'stream';
7
7
 
8
8
  import { Stream } from '@dxos/codec-protobuf';
9
- import { raise } from '@dxos/debug';
10
9
  import { PublicKey } from '@dxos/keys';
11
10
  import { log } from '@dxos/log';
12
11
  import {
@@ -20,10 +19,12 @@ import {
20
19
  } from '@dxos/protocols/proto/dxos/mesh/bridge';
21
20
  import { ComplexMap } from '@dxos/util';
22
21
 
23
- import { wrtc } from './webrtc';
22
+ import { WebRTCTransport } from './webrtc-transport';
24
23
 
25
24
  export class WebRTCTransportService implements BridgeService {
26
- protected peers = new ComplexMap<PublicKey, SimplePeer>(PublicKey.hash);
25
+ private readonly transports = new ComplexMap<PublicKey, { transport: WebRTCTransport; stream: Duplex }>(
26
+ PublicKey.hash
27
+ );
27
28
 
28
29
  // prettier-ignore
29
30
  constructor(
@@ -31,14 +32,23 @@ export class WebRTCTransportService implements BridgeService {
31
32
  ) {}
32
33
 
33
34
  open(request: ConnectionRequest): Stream<BridgeEvent> {
34
- return new Stream(({ ready, next, close }) => {
35
- log(
36
- `Creating webrtc connection initiator=${request.initiator} webrtcConfig=${JSON.stringify(this._webrtcConfig)}`
37
- );
38
- const peer = new SimplePeerConstructor({
35
+ const rpcStream: Stream<BridgeEvent> = new Stream(({ ready, next, close }) => {
36
+ const duplex: Duplex = new Duplex({
37
+ read: () => {},
38
+ write: function (chunk, _, callback) {
39
+ next({ data: { payload: chunk } });
40
+ callback();
41
+ }
42
+ });
43
+
44
+ const transport = new WebRTCTransport({
39
45
  initiator: request.initiator,
40
- wrtc: SimplePeerConstructor.WEBRTC_SUPPORT ? undefined : wrtc ?? raise(new Error('wrtc not available')),
41
- config: this._webrtcConfig
46
+ stream: duplex,
47
+ sendSignal: async (signal) => {
48
+ next({
49
+ signal: { payload: signal }
50
+ });
51
+ }
42
52
  });
43
53
 
44
54
  next({
@@ -47,23 +57,7 @@ export class WebRTCTransportService implements BridgeService {
47
57
  }
48
58
  });
49
59
 
50
- peer.on('data', async (payload) => {
51
- next({
52
- data: {
53
- payload
54
- }
55
- });
56
- });
57
-
58
- peer.on('signal', async (data) => {
59
- next({
60
- signal: {
61
- payload: { json: JSON.stringify(data) }
62
- }
63
- });
64
- });
65
-
66
- peer.on('connect', () => {
60
+ transport.connected.on(() => {
67
61
  next({
68
62
  connection: {
69
63
  state: ConnectionState.CONNECTED
@@ -71,7 +65,7 @@ export class WebRTCTransportService implements BridgeService {
71
65
  });
72
66
  });
73
67
 
74
- peer.on('error', async (err) => {
68
+ transport.errors.handle((err) => {
75
69
  next({
76
70
  connection: {
77
71
  state: ConnectionState.CLOSED,
@@ -81,7 +75,7 @@ export class WebRTCTransportService implements BridgeService {
81
75
  close(err);
82
76
  });
83
77
 
84
- peer.on('close', async () => {
78
+ transport.closed.on(() => {
85
79
  next({
86
80
  connection: {
87
81
  state: ConnectionState.CLOSED
@@ -90,26 +84,27 @@ export class WebRTCTransportService implements BridgeService {
90
84
  close();
91
85
  });
92
86
 
93
- this.peers.set(request.proxyId, peer);
94
-
95
87
  ready();
88
+ this.transports.set(request.proxyId, { transport, stream: duplex });
96
89
  });
90
+
91
+ return rpcStream;
97
92
  }
98
93
 
99
94
  async sendSignal({ proxyId, signal }: SignalRequest): Promise<void> {
100
- assert(this.peers.has(proxyId), 'Connection not ready to accept signals.');
101
- assert(signal.json, 'Signal message must contain signal data.');
102
- this.peers.get(proxyId)!.signal(JSON.parse(signal.json));
95
+ assert(this.transports.has(proxyId));
96
+ await this.transports.get(proxyId)!.transport.signal(signal);
103
97
  }
104
98
 
105
99
  async sendData({ proxyId, payload }: DataRequest): Promise<void> {
106
- assert(this.peers.has(proxyId));
107
- this.peers.get(proxyId)!.write(payload);
100
+ assert(this.transports.has(proxyId));
101
+ await this.transports.get(proxyId)!.stream.push(payload);
108
102
  }
109
103
 
110
104
  async close({ proxyId }: CloseRequest) {
111
- this.peers.get(proxyId)?.destroy();
112
- this.peers.delete(proxyId);
105
+ await this.transports.get(proxyId)?.transport.close();
106
+ await this.transports.get(proxyId)?.stream.end();
107
+ this.transports.delete(proxyId);
113
108
  log('Closed.');
114
109
  }
115
110
  }
@@ -18,15 +18,11 @@ import { WebRTCTransport } from './webrtc-transport';
18
18
  describe('WebRTCTransport', function () {
19
19
  // This doesn't clean up correctly and crashes with SIGSEGV / SIGABRT at the end. Probably an issue with wrtc package.
20
20
  it('open and close', async function () {
21
- const connection = new WebRTCTransport(
22
- true,
23
- new Duplex(),
24
- PublicKey.random(),
25
- PublicKey.random(),
26
- PublicKey.random(),
27
- PublicKey.random(),
28
- async (msg) => {}
29
- );
21
+ const connection = new WebRTCTransport({
22
+ initiator: true,
23
+ stream: new Duplex(),
24
+ sendSignal: async () => {}
25
+ });
30
26
 
31
27
  let callsCounter = 0;
32
28
  const closedCb = () => {
@@ -48,45 +44,36 @@ describe('WebRTCTransport', function () {
48
44
  const topic = PublicKey.random();
49
45
  const peer1Id = PublicKey.random();
50
46
  const peer2Id = PublicKey.random();
51
- const sessionId = PublicKey.random();
52
47
 
53
48
  const plugin1 = new TestProtocolPlugin(peer1Id.asBuffer());
54
49
  const protocolProvider1 = testProtocolProvider(topic.asBuffer(), peer1Id.asBuffer(), plugin1);
55
- const connection1 = new WebRTCTransport(
56
- true,
57
- protocolProvider1({
50
+ const connection1 = new WebRTCTransport({
51
+ initiator: true,
52
+ stream: protocolProvider1({
58
53
  channel: discoveryKey(topic),
59
54
  initiator: true
60
55
  }).stream,
61
- peer1Id,
62
- peer2Id,
63
- sessionId,
64
- topic,
65
- async (msg) => {
56
+ sendSignal: async (signal) => {
66
57
  await sleep(10);
67
- await connection2.signal(msg.data.signal);
58
+ await connection2.signal(signal);
68
59
  }
69
- );
60
+ });
70
61
  afterTest(() => connection1.close());
71
62
  afterTest(() => connection1.errors.assertNoUnhandledErrors());
72
63
 
73
64
  const plugin2 = new TestProtocolPlugin(peer2Id.asBuffer());
74
65
  const protocolProvider2 = testProtocolProvider(topic.asBuffer(), peer2Id.asBuffer(), plugin2);
75
- const connection2 = new WebRTCTransport(
76
- false,
77
- protocolProvider2({
66
+ const connection2 = new WebRTCTransport({
67
+ initiator: false,
68
+ stream: protocolProvider2({
78
69
  channel: discoveryKey(topic),
79
70
  initiator: false
80
71
  }).stream,
81
- peer2Id,
82
- peer1Id,
83
- sessionId,
84
- topic,
85
- async (msg) => {
72
+ sendSignal: async (signal) => {
86
73
  await sleep(10);
87
- await connection1.signal(msg.data.signal);
74
+ await connection1.signal(signal);
88
75
  }
89
- );
76
+ });
90
77
  afterTest(() => connection2.close());
91
78
  afterTest(() => connection2.errors.assertNoUnhandledErrors());
92
79
 
@@ -7,14 +7,19 @@ import SimplePeerConstructor, { Instance as SimplePeer } from 'simple-peer';
7
7
 
8
8
  import { Event } from '@dxos/async';
9
9
  import { ErrorStream, raise } from '@dxos/debug';
10
- import { PublicKey } from '@dxos/keys';
11
10
  import { log } from '@dxos/log';
12
11
  import { Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
13
12
 
14
- import { SignalMessage } from '../signal';
15
13
  import { Transport, TransportFactory } from './transport';
16
14
  import { wrtc } from './webrtc';
17
15
 
16
+ export type WebRTCTransportParams = {
17
+ initiator: boolean;
18
+ stream: NodeJS.ReadWriteStream;
19
+ webrtcConfig?: any;
20
+ sendSignal: (signal: Signal) => Promise<void>;
21
+ };
22
+
18
23
  /**
19
24
  * Implements Transport for WebRTC. Uses simple-peer under the hood.
20
25
  */
@@ -25,51 +30,27 @@ export class WebRTCTransport implements Transport {
25
30
  readonly connected = new Event();
26
31
  readonly errors = new ErrorStream();
27
32
 
28
- constructor(
29
- private readonly _initiator: boolean,
30
- private readonly _stream: NodeJS.ReadWriteStream,
31
- private readonly _ownId: PublicKey,
32
- private readonly _remoteId: PublicKey,
33
- private readonly _sessionId: PublicKey,
34
- private readonly _topic: PublicKey,
35
- private readonly _sendSignal: (msg: SignalMessage) => void,
36
- private readonly _webrtcConfig?: any
37
- ) {
38
- log('created connection', {
39
- id: this._ownId,
40
- topic: this._topic,
41
- remoteId: this._remoteId,
42
- initiator: this._initiator,
43
- config: this._webrtcConfig
44
- });
33
+ constructor(private readonly params: WebRTCTransportParams) {
34
+ log('created connection', params);
45
35
  this._peer = new SimplePeerConstructor({
46
- initiator: this._initiator,
36
+ initiator: this.params.initiator,
47
37
  wrtc: SimplePeerConstructor.WEBRTC_SUPPORT ? undefined : wrtc ?? raise(new Error('wrtc not available')),
48
- config: this._webrtcConfig
38
+ config: this.params.webrtcConfig
49
39
  });
50
40
 
51
41
  this._peer.on('signal', async (data) => {
52
- try {
53
- await this._sendSignal({
54
- author: this._ownId,
55
- recipient: this._remoteId,
56
- sessionId: this._sessionId,
57
- topic: this._topic,
58
- data: { signal: { json: JSON.stringify(data) } }
59
- });
60
- } catch (err: any) {
61
- this.errors.raise(err);
62
- }
42
+ log('signal', data);
43
+ await this.params.sendSignal({ json: JSON.stringify(data) });
63
44
  });
64
45
 
65
46
  this._peer.on('connect', () => {
66
- log('connected', { id: this._ownId, remoteId: this._remoteId });
67
- this._stream.pipe(this._peer!).pipe(this._stream);
47
+ log('connected');
48
+ this.params.stream.pipe(this._peer!).pipe(this.params.stream);
68
49
  this.connected.emit();
69
50
  });
70
51
 
71
52
  this._peer.on('close', async () => {
72
- log('closed', { id: this._ownId, remoteId: this._remoteId });
53
+ log('closed');
73
54
  await this._disconnectStreams();
74
55
  this.closed.emit();
75
56
  });
@@ -80,14 +61,6 @@ export class WebRTCTransport implements Transport {
80
61
  });
81
62
  }
82
63
 
83
- get remoteId() {
84
- return this._remoteId;
85
- }
86
-
87
- get sessionId() {
88
- return this._sessionId;
89
- }
90
-
91
64
  get peer() {
92
65
  return this._peer;
93
66
  }
@@ -96,6 +69,7 @@ export class WebRTCTransport implements Transport {
96
69
  log('closing...');
97
70
  await this._disconnectStreams();
98
71
  this._peer!.destroy();
72
+ this.closed.emit();
99
73
  log('closed');
100
74
  }
101
75
 
@@ -107,21 +81,15 @@ export class WebRTCTransport implements Transport {
107
81
 
108
82
  private async _disconnectStreams() {
109
83
  // TODO(rzadp): Find a way of unpiping this?
110
- this._stream.unpipe?.(this._peer)?.unpipe?.(this._stream);
84
+ this.params.stream.unpipe?.(this._peer)?.unpipe?.(this.params.stream);
111
85
  }
112
86
  }
113
87
 
114
88
  // TODO(dmaretskyi): Convert to class.
115
89
  export const createWebRTCTransportFactory = (webrtcConfig?: any): TransportFactory => ({
116
- create: (opts) =>
117
- new WebRTCTransport( // TODO(burdon): Refactor with to take opts in constructor.
118
- opts.initiator,
119
- opts.stream,
120
- opts.ownId,
121
- opts.remoteId,
122
- opts.sessionId,
123
- opts.topic,
124
- opts.sendSignal,
90
+ create: (params) =>
91
+ new WebRTCTransport({
92
+ ...params,
125
93
  webrtcConfig
126
- )
94
+ })
127
95
  });