@dxos/network-manager 0.3.8 → 0.3.9-main.14901ff
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/{chunk-H7XJ7HES.mjs → chunk-S2JHWVGQ.mjs} +325 -98
- package/dist/lib/browser/chunk-S2JHWVGQ.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +3 -3
- package/dist/lib/node/{chunk-RBHZCZH4.cjs → chunk-3SCPMSHV.cjs} +328 -91
- package/dist/lib/node/chunk-3SCPMSHV.cjs.map +7 -0
- package/dist/lib/node/{chunk-XE5JOIGD.cjs → chunk-DMWORJG3.cjs} +13 -4
- package/dist/lib/node/chunk-DMWORJG3.cjs.map +7 -0
- package/dist/lib/node/{datachannel-53JZPGFA.cjs → datachannel-ABYQKZRC.cjs} +9 -9
- package/dist/lib/node/{datachannel-53JZPGFA.cjs.map → datachannel-ABYQKZRC.cjs.map} +2 -2
- package/dist/lib/node/index.cjs +32 -32
- package/dist/lib/node/index.cjs.map +1 -1
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +21 -21
- package/dist/types/src/connection-log.d.ts.map +1 -1
- package/dist/types/src/swarm/connection.d.ts +4 -1
- package/dist/types/src/swarm/connection.d.ts.map +1 -1
- package/dist/types/src/transport/datachannel/rtc-peer-connection.d.ts +7 -0
- package/dist/types/src/transport/datachannel/rtc-peer-connection.d.ts.map +1 -1
- package/dist/types/src/transport/libdatachannel-transport.d.ts +3 -1
- package/dist/types/src/transport/libdatachannel-transport.d.ts.map +1 -1
- package/dist/types/src/transport/memory-transport.d.ts +3 -1
- package/dist/types/src/transport/memory-transport.d.ts.map +1 -1
- package/dist/types/src/transport/simplepeer-transport-proxy.d.ts +3 -1
- package/dist/types/src/transport/simplepeer-transport-proxy.d.ts.map +1 -1
- package/dist/types/src/transport/simplepeer-transport-service.d.ts +3 -1
- package/dist/types/src/transport/simplepeer-transport-service.d.ts.map +1 -1
- package/dist/types/src/transport/simplepeer-transport.d.ts +4 -1
- package/dist/types/src/transport/simplepeer-transport.d.ts.map +1 -1
- package/dist/types/src/transport/tcp-transport.browser.d.ts +3 -1
- package/dist/types/src/transport/tcp-transport.browser.d.ts.map +1 -1
- package/dist/types/src/transport/tcp-transport.d.ts +3 -1
- package/dist/types/src/transport/tcp-transport.d.ts.map +1 -1
- package/dist/types/src/transport/transport.d.ts +17 -0
- package/dist/types/src/transport/transport.d.ts.map +1 -1
- package/dist/types/src/wire-protocol.d.ts +1 -1
- package/dist/types/src/wire-protocol.d.ts.map +1 -1
- package/package.json +17 -17
- package/src/connection-log.ts +27 -1
- package/src/swarm/connection.ts +40 -6
- package/src/transport/datachannel/rtc-peer-connection.ts +13 -1
- package/src/transport/libdatachannel-transport.ts +44 -4
- package/src/transport/memory-transport.ts +14 -1
- package/src/transport/simplepeer-transport-proxy.ts +9 -1
- package/src/transport/simplepeer-transport-service.ts +14 -0
- package/src/transport/simplepeer-transport.ts +67 -3
- package/src/transport/tcp-transport.browser.ts +9 -1
- package/src/transport/tcp-transport.ts +19 -1
- package/src/transport/transport.ts +19 -0
- package/src/wire-protocol.ts +3 -3
- package/dist/lib/browser/chunk-H7XJ7HES.mjs.map +0 -7
- package/dist/lib/node/chunk-RBHZCZH4.cjs.map +0 -7
- package/dist/lib/node/chunk-XE5JOIGD.cjs.map +0 -7
|
@@ -22,7 +22,7 @@ import { ConnectionState, type BridgeEvent, type BridgeService } from '@dxos/pro
|
|
|
22
22
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
23
23
|
import { arrayToBuffer } from '@dxos/util';
|
|
24
24
|
|
|
25
|
-
import { type Transport, type TransportFactory, type TransportOptions } from './transport';
|
|
25
|
+
import { type Transport, type TransportFactory, type TransportOptions, type TransportStats } from './transport';
|
|
26
26
|
|
|
27
27
|
const RESP_MIN_THRESHOLD = 500;
|
|
28
28
|
const TIMEOUT_THRESHOLD = 10;
|
|
@@ -145,6 +145,14 @@ export class SimplePeerTransportProxy implements Transport {
|
|
|
145
145
|
.catch((err) => this.errors.raise(decodeError(err)));
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
async getDetails(): Promise<string> {
|
|
149
|
+
return (await this._params.bridgeService.getDetails({ proxyId: this._proxyId })).details;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async getStats(): Promise<TransportStats> {
|
|
153
|
+
return (await this._params.bridgeService.getStats({ proxyId: this._proxyId })).stats as TransportStats;
|
|
154
|
+
}
|
|
155
|
+
|
|
148
156
|
// TODO(burdon): Move open from constructor.
|
|
149
157
|
async destroy(): Promise<void> {
|
|
150
158
|
await this._ctx.dispose();
|
|
@@ -16,6 +16,10 @@ import {
|
|
|
16
16
|
type BridgeEvent,
|
|
17
17
|
ConnectionState,
|
|
18
18
|
type CloseRequest,
|
|
19
|
+
type DetailsRequest,
|
|
20
|
+
type DetailsResponse,
|
|
21
|
+
type StatsRequest,
|
|
22
|
+
type StatsResponse,
|
|
19
23
|
} from '@dxos/protocols/proto/dxos/mesh/bridge';
|
|
20
24
|
import { ComplexMap } from '@dxos/util';
|
|
21
25
|
|
|
@@ -113,6 +117,16 @@ export class SimplePeerTransportService implements BridgeService {
|
|
|
113
117
|
await this.transports.get(proxyId)!.transport.signal(signal);
|
|
114
118
|
}
|
|
115
119
|
|
|
120
|
+
async getDetails({ proxyId }: DetailsRequest): Promise<DetailsResponse> {
|
|
121
|
+
invariant(this.transports.has(proxyId));
|
|
122
|
+
return { details: await this.transports.get(proxyId)!.transport.getDetails() };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async getStats({ proxyId }: StatsRequest): Promise<StatsResponse> {
|
|
126
|
+
invariant(this.transports.has(proxyId));
|
|
127
|
+
return { stats: await this.transports.get(proxyId)!.transport.getStats() };
|
|
128
|
+
}
|
|
129
|
+
|
|
116
130
|
async sendData({ proxyId, payload }: DataRequest): Promise<void> {
|
|
117
131
|
if (this.transports.get(proxyId)?.state !== 'OPEN') {
|
|
118
132
|
log.debug('transport is closed');
|
|
@@ -13,7 +13,7 @@ import { log } from '@dxos/log';
|
|
|
13
13
|
import { ConnectionResetError, ConnectivityError, ProtocolError, UnknownProtocolError, trace } from '@dxos/protocols';
|
|
14
14
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
15
15
|
|
|
16
|
-
import { type Transport, type TransportFactory } from './transport';
|
|
16
|
+
import { type Transport, type TransportFactory, type TransportStats } from './transport';
|
|
17
17
|
import { wrtc } from './webrtc';
|
|
18
18
|
|
|
19
19
|
export type SimplePeerTransportParams = {
|
|
@@ -71,6 +71,7 @@ export class SimplePeerTransport implements Transport {
|
|
|
71
71
|
if (err.errorDetail === 'sctp-failure') {
|
|
72
72
|
this.errors.raise(new ConnectionResetError('sctp-failure from RTCError', err));
|
|
73
73
|
} else {
|
|
74
|
+
log.info('unknown RTCError', { err });
|
|
74
75
|
this.errors.raise(new UnknownProtocolError('unknown RTCError', err));
|
|
75
76
|
}
|
|
76
77
|
// catch more generic simple-peer errors: https://github.com/feross/simple-peer/blob/master/README.md#error-codes
|
|
@@ -80,10 +81,12 @@ export class SimplePeerTransport implements Transport {
|
|
|
80
81
|
case 'ERR_WEBRTC_SUPPORT':
|
|
81
82
|
this.errors.raise(new ProtocolError('WebRTC not supported', err));
|
|
82
83
|
break;
|
|
84
|
+
case 'ERR_SIGNALING':
|
|
85
|
+
this.errors.raise(new ConnectivityError('signaling failure', err));
|
|
86
|
+
break;
|
|
83
87
|
case 'ERR_ICE_CONNECTION_FAILURE':
|
|
84
88
|
case 'ERR_DATA_CHANNEL':
|
|
85
89
|
case 'ERR_CONNECTION_FAILURE':
|
|
86
|
-
case 'ERR_SIGNALING':
|
|
87
90
|
this.errors.raise(new ConnectivityError('unknown communication failure', err));
|
|
88
91
|
break;
|
|
89
92
|
// errors due to library issues or improper API usage
|
|
@@ -109,7 +112,7 @@ export class SimplePeerTransport implements Transport {
|
|
|
109
112
|
(this._peer as any)._pc.getStats().then((stats: any) => {
|
|
110
113
|
log.info('report after webrtc error', {
|
|
111
114
|
config: this.params.webrtcConfig,
|
|
112
|
-
stats,
|
|
115
|
+
stats: Object.fromEntries((stats as any).entries()),
|
|
113
116
|
});
|
|
114
117
|
});
|
|
115
118
|
}
|
|
@@ -119,9 +122,69 @@ export class SimplePeerTransport implements Transport {
|
|
|
119
122
|
|
|
120
123
|
await this.destroy();
|
|
121
124
|
});
|
|
125
|
+
|
|
122
126
|
log.trace('dxos.mesh.webrtc-transport.constructor', trace.end({ id: this._instanceId }));
|
|
123
127
|
}
|
|
124
128
|
|
|
129
|
+
async getStats(): Promise<TransportStats> {
|
|
130
|
+
const stats = await this._getStats();
|
|
131
|
+
if (!stats) {
|
|
132
|
+
return {
|
|
133
|
+
bytesSent: 0,
|
|
134
|
+
bytesReceived: 0,
|
|
135
|
+
packetsSent: 0,
|
|
136
|
+
packetsReceived: 0,
|
|
137
|
+
rawStats: {},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// TODO(nf): transport or candidatePair?
|
|
142
|
+
return {
|
|
143
|
+
bytesSent: stats.transport.bytesSent,
|
|
144
|
+
bytesReceived: stats.transport.bytesReceived,
|
|
145
|
+
packetsSent: stats.transport.messagesSent,
|
|
146
|
+
packetsReceived: stats.transport.messagesReceived,
|
|
147
|
+
rawStats: stats.raw,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async _getStats(): Promise<any> {
|
|
152
|
+
if (typeof (this._peer as any)?._pc?.getStats !== 'function') {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
return await (this._peer as any)._pc.getStats().then((stats: any) => {
|
|
156
|
+
const statsEntries = Array.from(stats.entries() as any[]);
|
|
157
|
+
const transport = statsEntries.filter((s: any) => s[1].type === 'transport')[0][1];
|
|
158
|
+
const candidatePair = statsEntries.filter((s: any) => s[0] === transport.selectedCandidatePairId);
|
|
159
|
+
let selectedCandidatePair: any;
|
|
160
|
+
let remoteCandidate: any;
|
|
161
|
+
if (candidatePair.length > 0) {
|
|
162
|
+
selectedCandidatePair = candidatePair[0][1];
|
|
163
|
+
remoteCandidate = statsEntries.filter((s: any) => s[0] === selectedCandidatePair.remoteCandidateId)[0][1];
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
datachannel: statsEntries.filter((s: any) => s[1].type === 'data-channel')[0][1],
|
|
167
|
+
transport,
|
|
168
|
+
selectedCandidatePair,
|
|
169
|
+
remoteCandidate,
|
|
170
|
+
raw: Object.fromEntries(stats.entries()),
|
|
171
|
+
};
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async getDetails(): Promise<string> {
|
|
176
|
+
const stats = await this._getStats();
|
|
177
|
+
const rc = stats?.remoteCandidate;
|
|
178
|
+
if (!rc) {
|
|
179
|
+
return 'unavailable';
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (rc.relay) {
|
|
183
|
+
return `${rc.ip}:${rc.port}/${rc.protocol} relay for XXX ${rc.candidateType}`;
|
|
184
|
+
}
|
|
185
|
+
return `${rc.ip}:${rc.port}/${rc.protocol} ${rc.candidateType}`;
|
|
186
|
+
}
|
|
187
|
+
|
|
125
188
|
async destroy() {
|
|
126
189
|
log('closing...');
|
|
127
190
|
if (this._closed) {
|
|
@@ -130,6 +193,7 @@ export class SimplePeerTransport implements Transport {
|
|
|
130
193
|
this._closed = true;
|
|
131
194
|
this._disconnectStreams();
|
|
132
195
|
this._peer!.destroy();
|
|
196
|
+
this._closed = true;
|
|
133
197
|
this.closed.emit();
|
|
134
198
|
log('closed');
|
|
135
199
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Event } from '@dxos/async';
|
|
6
6
|
import { ErrorStream } from '@dxos/debug';
|
|
7
7
|
|
|
8
|
-
import { type Transport, type TransportFactory } from './transport';
|
|
8
|
+
import { type Transport, type TransportFactory, type TransportStats } from './transport';
|
|
9
9
|
|
|
10
10
|
// NOTE: Browser stub.
|
|
11
11
|
|
|
@@ -25,4 +25,12 @@ export class TcpTransport implements Transport {
|
|
|
25
25
|
signal() {
|
|
26
26
|
throw new Error('Method not implemented.');
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
async getStats(): Promise<TransportStats> {
|
|
30
|
+
throw new Error('Method not implemented.');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async getDetails(): Promise<string> {
|
|
34
|
+
throw new Error('Method not implemented.');
|
|
35
|
+
}
|
|
28
36
|
}
|
|
@@ -9,7 +9,7 @@ import { ErrorStream } from '@dxos/debug';
|
|
|
9
9
|
import { log } from '@dxos/log';
|
|
10
10
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
11
11
|
|
|
12
|
-
import { type Transport, type TransportFactory, type TransportOptions } from './transport';
|
|
12
|
+
import { type Transport, type TransportFactory, type TransportOptions, type TransportStats } from './transport';
|
|
13
13
|
|
|
14
14
|
export const TcpTransportFactory: TransportFactory = {
|
|
15
15
|
createTransport: (params) => new TcpTransport(params),
|
|
@@ -87,6 +87,24 @@ export class TcpTransport implements Transport {
|
|
|
87
87
|
socket.connect({ port: payload.port, host: 'localhost' });
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
async getDetails(): Promise<string> {
|
|
91
|
+
if (this.options.initiator) {
|
|
92
|
+
const { port, address } = this._server?.address() as AddressInfo;
|
|
93
|
+
return `LISTEN ${address}:${port}`;
|
|
94
|
+
}
|
|
95
|
+
const { port, address } = this._socket?.address() as AddressInfo;
|
|
96
|
+
return `ACCEPT ${address}:${port}`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async getStats(): Promise<TransportStats> {
|
|
100
|
+
return {
|
|
101
|
+
bytesSent: 0,
|
|
102
|
+
bytesReceived: 0,
|
|
103
|
+
packetsSent: 0,
|
|
104
|
+
packetsReceived: 0,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
90
108
|
private _handleSocket(socket: Socket) {
|
|
91
109
|
log('handling socket', { remotePort: socket.remotePort, localPort: socket.localPort });
|
|
92
110
|
this._socket = socket;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { type Event } from '@dxos/async';
|
|
6
6
|
import { type ErrorStream } from '@dxos/debug';
|
|
7
|
+
import { type PublicKey } from '@dxos/keys';
|
|
7
8
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
8
9
|
|
|
9
10
|
export enum TransportKind {
|
|
@@ -22,6 +23,14 @@ export interface Transport {
|
|
|
22
23
|
connected: Event;
|
|
23
24
|
errors: ErrorStream;
|
|
24
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Transport-specfic stats.
|
|
28
|
+
*/
|
|
29
|
+
getStats(): Promise<TransportStats>;
|
|
30
|
+
/**
|
|
31
|
+
* Transport-specfic connection details.
|
|
32
|
+
*/
|
|
33
|
+
getDetails(): Promise<string>;
|
|
25
34
|
destroy(): Promise<void>;
|
|
26
35
|
signal(signal: Signal): void;
|
|
27
36
|
}
|
|
@@ -43,6 +52,8 @@ export type TransportOptions = {
|
|
|
43
52
|
sendSignal: (signal: Signal) => Promise<void>; // TODO(burdon): Remove async?
|
|
44
53
|
|
|
45
54
|
timeout?: number;
|
|
55
|
+
|
|
56
|
+
sessionId?: PublicKey;
|
|
46
57
|
};
|
|
47
58
|
|
|
48
59
|
/**
|
|
@@ -51,3 +62,11 @@ export type TransportOptions = {
|
|
|
51
62
|
export interface TransportFactory {
|
|
52
63
|
createTransport(options: TransportOptions): Transport;
|
|
53
64
|
}
|
|
65
|
+
|
|
66
|
+
export type TransportStats = {
|
|
67
|
+
bytesSent: number;
|
|
68
|
+
bytesReceived: number;
|
|
69
|
+
packetsSent: number;
|
|
70
|
+
packetsReceived: number;
|
|
71
|
+
rawStats?: any;
|
|
72
|
+
};
|
package/src/wire-protocol.ts
CHANGED
|
@@ -23,7 +23,7 @@ export type WireProtocolProvider = (params: WireProtocolParams) => WireProtocol;
|
|
|
23
23
|
export interface WireProtocol {
|
|
24
24
|
stream: Duplex;
|
|
25
25
|
|
|
26
|
-
open(): Promise<void>;
|
|
26
|
+
open(sessionId?: PublicKey): Promise<void>;
|
|
27
27
|
close(): Promise<void>;
|
|
28
28
|
abort(): Promise<void>;
|
|
29
29
|
}
|
|
@@ -40,8 +40,8 @@ export const createTeleportProtocolFactory = (
|
|
|
40
40
|
const teleport = new Teleport(params);
|
|
41
41
|
return {
|
|
42
42
|
stream: teleport.stream,
|
|
43
|
-
open: async () => {
|
|
44
|
-
await teleport.open();
|
|
43
|
+
open: async (sessionId?: PublicKey) => {
|
|
44
|
+
await teleport.open(sessionId);
|
|
45
45
|
await onConnection(teleport);
|
|
46
46
|
},
|
|
47
47
|
close: async () => {
|