@dxos/network-manager 0.3.8 → 0.3.9-main.03b62b6
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-KGZ5C6JO.mjs} +407 -118
- package/dist/lib/browser/chunk-KGZ5C6JO.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-XE5JOIGD.cjs → chunk-JDKM4UPJ.cjs} +21 -13
- package/dist/lib/node/chunk-JDKM4UPJ.cjs.map +7 -0
- package/dist/lib/node/{chunk-RBHZCZH4.cjs → chunk-WUBZ4UOJ.cjs} +410 -111
- package/dist/lib/node/chunk-WUBZ4UOJ.cjs.map +7 -0
- package/dist/lib/node/{datachannel-53JZPGFA.cjs → datachannel-3VTTIMR5.cjs} +9 -9
- package/dist/lib/node/{datachannel-53JZPGFA.cjs.map → datachannel-3VTTIMR5.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/topology/mmst-topology.d.ts +1 -0
- package/dist/types/src/topology/mmst-topology.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 +7 -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/topology/mmst-topology.ts +34 -6
- package/src/transport/datachannel/rtc-peer-connection.ts +20 -12
- package/src/transport/libdatachannel-transport.test.ts +0 -4
- 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 +70 -4
- 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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Event } from '@dxos/async';
|
|
3
3
|
import { ErrorStream } from '@dxos/debug';
|
|
4
4
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
5
|
-
import { type Transport, type TransportFactory } from './transport';
|
|
5
|
+
import { type Transport, type TransportFactory, type TransportStats } from './transport';
|
|
6
6
|
export type SimplePeerTransportParams = {
|
|
7
7
|
initiator: boolean;
|
|
8
8
|
stream: NodeJS.ReadWriteStream;
|
|
@@ -21,7 +21,13 @@ export declare class SimplePeerTransport implements Transport {
|
|
|
21
21
|
readonly connected: Event<void>;
|
|
22
22
|
readonly errors: ErrorStream;
|
|
23
23
|
private readonly _instanceId;
|
|
24
|
+
/**
|
|
25
|
+
* @params opts.config formatted as per https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection
|
|
26
|
+
*/
|
|
24
27
|
constructor(params: SimplePeerTransportParams);
|
|
28
|
+
getStats(): Promise<TransportStats>;
|
|
29
|
+
_getStats(): Promise<any>;
|
|
30
|
+
getDetails(): Promise<string>;
|
|
25
31
|
destroy(): Promise<void>;
|
|
26
32
|
signal(signal: Signal): void;
|
|
27
33
|
private _disconnectStreams;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simplepeer-transport.d.ts","sourceRoot":"","sources":["../../../../src/transport/simplepeer-transport.ts"],"names":[],"mappings":";AAQA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,WAAW,EAAS,MAAM,aAAa,CAAC;AAIjD,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAEpE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"simplepeer-transport.d.ts","sourceRoot":"","sources":["../../../../src/transport/simplepeer-transport.ts"],"names":[],"mappings":";AAQA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,WAAW,EAAS,MAAM,aAAa,CAAC;AAIjD,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAEpE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAGzF,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,eAAe,CAAC;IAC/B,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C,CAAC;AAEF;;GAEG;AACH,qBAAa,mBAAoB,YAAW,SAAS;IAcvC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAbnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IAEvB,QAAQ,CAAC,MAAM,cAAe;IAC9B,QAAQ,CAAC,SAAS,cAAe;IACjC,QAAQ,CAAC,MAAM,cAAqB;IAEpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;IAE1D;;OAEG;gBAC0B,MAAM,EAAE,yBAAyB;IAyFxD,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC;IAsBnC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC;IAwBzB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAa7B,OAAO;IAYb,MAAM,CAAC,MAAM,EAAE,MAAM;IASrB,OAAO,CAAC,kBAAkB;CAM3B;AAED,eAAO,MAAM,gCAAgC,kBAAmB,GAAG,KAAG,gBAMpE,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Event } from '@dxos/async';
|
|
2
2
|
import { ErrorStream } from '@dxos/debug';
|
|
3
|
-
import { type Transport, type TransportFactory } from './transport';
|
|
3
|
+
import { type Transport, type TransportFactory, type TransportStats } from './transport';
|
|
4
4
|
export declare const TcpTransportFactory: TransportFactory;
|
|
5
5
|
export declare class TcpTransport implements Transport {
|
|
6
6
|
readonly closed: Event<void>;
|
|
@@ -8,5 +8,7 @@ export declare class TcpTransport implements Transport {
|
|
|
8
8
|
readonly errors: ErrorStream;
|
|
9
9
|
destroy(): Promise<void>;
|
|
10
10
|
signal(): void;
|
|
11
|
+
getStats(): Promise<TransportStats>;
|
|
12
|
+
getDetails(): Promise<string>;
|
|
11
13
|
}
|
|
12
14
|
//# sourceMappingURL=tcp-transport.browser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tcp-transport.browser.d.ts","sourceRoot":"","sources":["../../../../src/transport/tcp-transport.browser.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"tcp-transport.browser.d.ts","sourceRoot":"","sources":["../../../../src/transport/tcp-transport.browser.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAIzF,eAAO,MAAM,mBAAmB,EAAE,gBAEjC,CAAC;AAEF,qBAAa,YAAa,YAAW,SAAS;IAC5C,SAAgB,MAAM,cAAqB;IAC3C,SAAgB,SAAS,cAAqB;IAC9C,SAAgB,MAAM,cAAqB;IAErC,OAAO;IAIb,MAAM;IAIA,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC;IAInC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;CAGpC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Event } from '@dxos/async';
|
|
2
2
|
import { ErrorStream } from '@dxos/debug';
|
|
3
3
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
4
|
-
import { type Transport, type TransportFactory, type TransportOptions } from './transport';
|
|
4
|
+
import { type Transport, type TransportFactory, type TransportOptions, type TransportStats } from './transport';
|
|
5
5
|
export declare const TcpTransportFactory: TransportFactory;
|
|
6
6
|
/**
|
|
7
7
|
* Fake transport.
|
|
@@ -18,6 +18,8 @@ export declare class TcpTransport implements Transport {
|
|
|
18
18
|
constructor(options: TransportOptions);
|
|
19
19
|
destroy(): Promise<void>;
|
|
20
20
|
signal({ payload }: Signal): void;
|
|
21
|
+
getDetails(): Promise<string>;
|
|
22
|
+
getStats(): Promise<TransportStats>;
|
|
21
23
|
private _handleSocket;
|
|
22
24
|
}
|
|
23
25
|
//# sourceMappingURL=tcp-transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tcp-transport.d.ts","sourceRoot":"","sources":["../../../../src/transport/tcp-transport.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAEpE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"tcp-transport.d.ts","sourceRoot":"","sources":["../../../../src/transport/tcp-transport.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAEpE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhH,eAAO,MAAM,mBAAmB,EAAE,gBAEjC,CAAC;AAEF;;GAEG;AACH,qBAAa,YAAa,YAAW,SAAS;IAYhC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAXpC,OAAO,CAAC,OAAO,CAAC,CAAqB;IACrC,OAAO,CAAC,OAAO,CAAC,CAAqB;IAErC,SAAgB,MAAM,cAAqB;IAC3C,SAAgB,SAAS,cAAqB;IAC9C,SAAgB,MAAM,cAAqB;IAE3C,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,UAAU,CAAS;gBAEE,OAAO,EAAE,gBAAgB;IAsChD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM;IAWpB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAS7B,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC;IASzC,OAAO,CAAC,aAAa;CAiBtB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { type Event } from '@dxos/async';
|
|
3
3
|
import { type ErrorStream } from '@dxos/debug';
|
|
4
|
+
import { type PublicKey } from '@dxos/keys';
|
|
4
5
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
5
6
|
export declare enum TransportKind {
|
|
6
7
|
SIMPLE_PEER = "SIMPLE_PEER",
|
|
@@ -16,6 +17,14 @@ export interface Transport {
|
|
|
16
17
|
closed: Event;
|
|
17
18
|
connected: Event;
|
|
18
19
|
errors: ErrorStream;
|
|
20
|
+
/**
|
|
21
|
+
* Transport-specfic stats.
|
|
22
|
+
*/
|
|
23
|
+
getStats(): Promise<TransportStats>;
|
|
24
|
+
/**
|
|
25
|
+
* Transport-specfic connection details.
|
|
26
|
+
*/
|
|
27
|
+
getDetails(): Promise<string>;
|
|
19
28
|
destroy(): Promise<void>;
|
|
20
29
|
signal(signal: Signal): void;
|
|
21
30
|
}
|
|
@@ -33,6 +42,7 @@ export type TransportOptions = {
|
|
|
33
42
|
*/
|
|
34
43
|
sendSignal: (signal: Signal) => Promise<void>;
|
|
35
44
|
timeout?: number;
|
|
45
|
+
sessionId?: PublicKey;
|
|
36
46
|
};
|
|
37
47
|
/**
|
|
38
48
|
*
|
|
@@ -40,4 +50,11 @@ export type TransportOptions = {
|
|
|
40
50
|
export interface TransportFactory {
|
|
41
51
|
createTransport(options: TransportOptions): Transport;
|
|
42
52
|
}
|
|
53
|
+
export type TransportStats = {
|
|
54
|
+
bytesSent: number;
|
|
55
|
+
bytesReceived: number;
|
|
56
|
+
packetsSent: number;
|
|
57
|
+
packetsReceived: number;
|
|
58
|
+
rawStats?: any;
|
|
59
|
+
};
|
|
43
60
|
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../../src/transport/transport.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAEpE,oBAAY,aAAa;IACvB,WAAW,gBAAgB;IAC3B,cAAc,mBAAmB;IACjC,iBAAiB,sBAAsB;IACvC,MAAM,WAAW;IACjB,GAAG,QAAQ;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,KAAK,CAAC;IACd,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IAEpB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC,eAAe,CAAC;IAE/B;;OAEG;IACH,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../../src/transport/transport.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAEpE,oBAAY,aAAa;IACvB,WAAW,gBAAgB;IAC3B,cAAc,mBAAmB;IACjC,iBAAiB,sBAAsB;IACvC,MAAM,WAAW;IACjB,GAAG,QAAQ;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,KAAK,CAAC;IACd,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IAEpB;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IACpC;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC,eAAe,CAAC;IAE/B;;OAEG;IACH,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACvD;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB,CAAC"}
|
|
@@ -15,7 +15,7 @@ export type WireProtocolProvider = (params: WireProtocolParams) => WireProtocol;
|
|
|
15
15
|
*/
|
|
16
16
|
export interface WireProtocol {
|
|
17
17
|
stream: Duplex;
|
|
18
|
-
open(): Promise<void>;
|
|
18
|
+
open(sessionId?: PublicKey): Promise<void>;
|
|
19
19
|
close(): Promise<void>;
|
|
20
20
|
abort(): Promise<void>;
|
|
21
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wire-protocol.d.ts","sourceRoot":"","sources":["../../../src/wire-protocol.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,SAAS,CAAC;IACvB,YAAY,EAAE,SAAS,CAAC;IACxB,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,kBAAkB,KAAK,YAAY,CAAC;AAEhF;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IAEf,IAAI,
|
|
1
|
+
{"version":3,"file":"wire-protocol.d.ts","sourceRoot":"","sources":["../../../src/wire-protocol.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,SAAS,CAAC;IACvB,YAAY,EAAE,SAAS,CAAC;IACxB,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,kBAAkB,KAAK,YAAY,CAAC;AAEhF;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IAEf,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,4BACf,QAAQ,KAAK,QAAQ,IAAI,CAAC,KAClD,oBAiBF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/network-manager",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.9-main.03b62b6",
|
|
4
4
|
"description": "Network Manager",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -31,21 +31,21 @@
|
|
|
31
31
|
"tiny-invariant": "^1.3.1",
|
|
32
32
|
"ws": "^8.14.2",
|
|
33
33
|
"xor-distance": "^2.0.0",
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/
|
|
39
|
-
"@dxos/invariant": "0.3.
|
|
40
|
-
"@dxos/
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/keys": "0.3.
|
|
43
|
-
"@dxos/
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/teleport": "0.3.
|
|
48
|
-
"@dxos/
|
|
34
|
+
"@dxos/async": "0.3.9-main.03b62b6",
|
|
35
|
+
"@dxos/codec-protobuf": "0.3.9-main.03b62b6",
|
|
36
|
+
"@dxos/context": "0.3.9-main.03b62b6",
|
|
37
|
+
"@dxos/credentials": "0.3.9-main.03b62b6",
|
|
38
|
+
"@dxos/debug": "0.3.9-main.03b62b6",
|
|
39
|
+
"@dxos/invariant": "0.3.9-main.03b62b6",
|
|
40
|
+
"@dxos/crypto": "0.3.9-main.03b62b6",
|
|
41
|
+
"@dxos/log": "0.3.9-main.03b62b6",
|
|
42
|
+
"@dxos/keys": "0.3.9-main.03b62b6",
|
|
43
|
+
"@dxos/node-std": "0.3.9-main.03b62b6",
|
|
44
|
+
"@dxos/protocols": "0.3.9-main.03b62b6",
|
|
45
|
+
"@dxos/messaging": "0.3.9-main.03b62b6",
|
|
46
|
+
"@dxos/util": "0.3.9-main.03b62b6",
|
|
47
|
+
"@dxos/teleport": "0.3.9-main.03b62b6",
|
|
48
|
+
"@dxos/rpc": "0.3.9-main.03b62b6"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@swc-node/register": "1.5.4",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"earljs": "~0.1.10",
|
|
56
56
|
"fast-check": "~3.3.0",
|
|
57
57
|
"typescript": "^5.2.2",
|
|
58
|
-
"@dxos/signal": "0.3.
|
|
58
|
+
"@dxos/signal": "0.3.9-main.03b62b6"
|
|
59
59
|
},
|
|
60
60
|
"publishConfig": {
|
|
61
61
|
"access": "public"
|
package/src/connection-log.ts
CHANGED
|
@@ -12,6 +12,8 @@ import { ComplexMap } from '@dxos/util';
|
|
|
12
12
|
import { ConnectionState, type Swarm } from './swarm';
|
|
13
13
|
import { type WireProtocol } from './wire-protocol';
|
|
14
14
|
|
|
15
|
+
const CONNECTION_GC_THRESHOLD = 1000 * 60 * 15;
|
|
16
|
+
|
|
15
17
|
export enum EventType {
|
|
16
18
|
CONNECTION_STATE_CHANGED = 'CONNECTION_STATE_CHANGED',
|
|
17
19
|
PROTOCOL_ERROR = 'PROTOCOL_ERROR',
|
|
@@ -57,17 +59,25 @@ export class ConnectionLog {
|
|
|
57
59
|
transport: connection.transport && Object.getPrototypeOf(connection.transport).constructor.name,
|
|
58
60
|
protocolExtensions: [], // TODO(dmaretskyi): Fix.
|
|
59
61
|
events: [],
|
|
62
|
+
lastUpdate: new Date(),
|
|
60
63
|
};
|
|
61
64
|
info.connections!.push(connectionInfo);
|
|
62
65
|
this.update.emit();
|
|
63
66
|
|
|
64
|
-
connection.stateChanged.on((state) => {
|
|
67
|
+
connection.stateChanged.on(async (state) => {
|
|
65
68
|
connectionInfo.state = state;
|
|
66
69
|
connectionInfo.closeReason = connection.closeReason;
|
|
70
|
+
connectionInfo.lastUpdate = new Date();
|
|
67
71
|
connectionInfo.events!.push({
|
|
68
72
|
type: EventType.CONNECTION_STATE_CHANGED,
|
|
69
73
|
newState: state,
|
|
70
74
|
});
|
|
75
|
+
|
|
76
|
+
if (state === ConnectionState.CONNECTED) {
|
|
77
|
+
const details = await connection.transport?.getDetails();
|
|
78
|
+
connectionInfo.transportDetails = details;
|
|
79
|
+
}
|
|
80
|
+
|
|
71
81
|
this.update.emit();
|
|
72
82
|
});
|
|
73
83
|
|
|
@@ -75,9 +85,19 @@ export class ConnectionLog {
|
|
|
75
85
|
connectionInfo.readBufferSize = stats.readBufferSize;
|
|
76
86
|
connectionInfo.writeBufferSize = stats.writeBufferSize;
|
|
77
87
|
connectionInfo.streams = stats.channels;
|
|
88
|
+
connectionInfo.lastUpdate = new Date();
|
|
78
89
|
this.update.emit();
|
|
79
90
|
});
|
|
80
91
|
|
|
92
|
+
connection.transportStats?.on((stats) => {
|
|
93
|
+
connectionInfo.transportBytesSent = stats.bytesSent;
|
|
94
|
+
connectionInfo.transportBytesReceived = stats.bytesReceived;
|
|
95
|
+
connectionInfo.transportPacketsSent = stats.packetsSent;
|
|
96
|
+
connectionInfo.transportPacketsReceived = stats.packetsReceived;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
gcSwarm(info);
|
|
100
|
+
|
|
81
101
|
// connection.protocol.protocol?.error.on((error) => {
|
|
82
102
|
// connectionInfo.events!.push({
|
|
83
103
|
// type: EventType.PROTOCOL_ERROR,
|
|
@@ -111,3 +131,9 @@ export class ConnectionLog {
|
|
|
111
131
|
this.update.emit();
|
|
112
132
|
}
|
|
113
133
|
}
|
|
134
|
+
|
|
135
|
+
const gcSwarm = (swarm: SwarmInfo) => {
|
|
136
|
+
swarm.connections = swarm.connections?.filter((connection) => {
|
|
137
|
+
return connection.lastUpdate ? Date.now() - connection.lastUpdate.getTime() < CONNECTION_GC_THRESHOLD : true;
|
|
138
|
+
});
|
|
139
|
+
};
|
package/src/swarm/connection.ts
CHANGED
|
@@ -2,24 +2,25 @@
|
|
|
2
2
|
// Copyright 2021 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { DeferredTask, Event, sleep, scheduleTask, synchronized } from '@dxos/async';
|
|
5
|
+
import { DeferredTask, Event, sleep, scheduleTask, scheduleTaskInterval, synchronized } from '@dxos/async';
|
|
6
6
|
import { Context, cancelWithContext } from '@dxos/context';
|
|
7
7
|
import { ErrorStream } from '@dxos/debug';
|
|
8
8
|
import { invariant } from '@dxos/invariant';
|
|
9
9
|
import { PublicKey } from '@dxos/keys';
|
|
10
|
-
import { log } from '@dxos/log';
|
|
10
|
+
import { log, logInfo } from '@dxos/log';
|
|
11
11
|
import {
|
|
12
12
|
CancelledError,
|
|
13
13
|
ProtocolError,
|
|
14
14
|
ConnectionResetError,
|
|
15
15
|
ConnectivityError,
|
|
16
|
+
TimeoutError,
|
|
16
17
|
UnknownProtocolError,
|
|
17
18
|
trace,
|
|
18
19
|
} from '@dxos/protocols';
|
|
19
20
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
20
21
|
|
|
21
22
|
import { type SignalMessage, type SignalMessenger } from '../signal';
|
|
22
|
-
import { type Transport, type TransportFactory } from '../transport';
|
|
23
|
+
import { type Transport, type TransportFactory, type TransportStats } from '../transport';
|
|
23
24
|
import { type WireProtocol } from '../wire-protocol';
|
|
24
25
|
|
|
25
26
|
/**
|
|
@@ -33,6 +34,8 @@ const STARTING_SIGNALLING_DELAY = 10;
|
|
|
33
34
|
*/
|
|
34
35
|
const TRANSPORT_CONNECTION_TIMEOUT = 10_000;
|
|
35
36
|
|
|
37
|
+
const TRANSPORT_STATS_INTERVAL = 5_000;
|
|
38
|
+
|
|
36
39
|
/**
|
|
37
40
|
* Maximum delay between signal batches.
|
|
38
41
|
*/
|
|
@@ -109,6 +112,8 @@ export class Connection {
|
|
|
109
112
|
|
|
110
113
|
public _instanceId = PublicKey.random().toHex();
|
|
111
114
|
|
|
115
|
+
public readonly transportStats = new Event<TransportStats>();
|
|
116
|
+
|
|
112
117
|
private readonly _signalSendTask = new DeferredTask(this._ctx, async () => {
|
|
113
118
|
await this._flushSignalBuffer();
|
|
114
119
|
});
|
|
@@ -135,6 +140,11 @@ export class Connection {
|
|
|
135
140
|
});
|
|
136
141
|
}
|
|
137
142
|
|
|
143
|
+
@logInfo
|
|
144
|
+
get sessionIdString(): string {
|
|
145
|
+
return this.sessionId.truncate();
|
|
146
|
+
}
|
|
147
|
+
|
|
138
148
|
get state() {
|
|
139
149
|
return this._state;
|
|
140
150
|
}
|
|
@@ -164,7 +174,7 @@ export class Connection {
|
|
|
164
174
|
this._changeState(ConnectionState.CONNECTING);
|
|
165
175
|
|
|
166
176
|
// TODO(dmaretskyi): Initialize only after the transport has established connection.
|
|
167
|
-
this._protocol.open().catch((err) => {
|
|
177
|
+
this._protocol.open(this.sessionId).catch((err) => {
|
|
168
178
|
this.errors.raise(err);
|
|
169
179
|
});
|
|
170
180
|
|
|
@@ -177,8 +187,10 @@ export class Connection {
|
|
|
177
187
|
scheduleTask(
|
|
178
188
|
this.connectedTimeoutContext,
|
|
179
189
|
async () => {
|
|
180
|
-
log.info(
|
|
181
|
-
await this.abort(
|
|
190
|
+
log.info(`timeout waiting ${TRANSPORT_CONNECTION_TIMEOUT / 1000}s for transport to connect, aborting`);
|
|
191
|
+
await this.abort(new TimeoutError(`${TRANSPORT_CONNECTION_TIMEOUT / 1000}s for transport to connect`)).catch(
|
|
192
|
+
(err) => this.errors.raise(err),
|
|
193
|
+
);
|
|
182
194
|
},
|
|
183
195
|
TRANSPORT_CONNECTION_TIMEOUT,
|
|
184
196
|
);
|
|
@@ -188,12 +200,15 @@ export class Connection {
|
|
|
188
200
|
initiator: this.initiator,
|
|
189
201
|
stream: this._protocol.stream,
|
|
190
202
|
sendSignal: async (signal) => this._sendSignal(signal),
|
|
203
|
+
sessionId: this.sessionId,
|
|
191
204
|
});
|
|
192
205
|
|
|
193
206
|
this._transport.connected.once(async () => {
|
|
194
207
|
this._changeState(ConnectionState.CONNECTED);
|
|
195
208
|
await this.connectedTimeoutContext.dispose();
|
|
196
209
|
this._callbacks?.onConnected?.();
|
|
210
|
+
|
|
211
|
+
scheduleTaskInterval(this._ctx, async () => this._emitTransportStats(), TRANSPORT_STATS_INTERVAL);
|
|
197
212
|
});
|
|
198
213
|
|
|
199
214
|
this._transport.closed.once(() => {
|
|
@@ -312,6 +327,18 @@ export class Connection {
|
|
|
312
327
|
} catch (err: any) {
|
|
313
328
|
log.catch(err);
|
|
314
329
|
}
|
|
330
|
+
} else {
|
|
331
|
+
log.info(`graceful close requested when we were in ${lastState} state? aborting`);
|
|
332
|
+
try {
|
|
333
|
+
await this._protocol.abort();
|
|
334
|
+
} catch (err: any) {
|
|
335
|
+
log.catch(err);
|
|
336
|
+
}
|
|
337
|
+
try {
|
|
338
|
+
await this._transport?.destroy();
|
|
339
|
+
} catch (err: any) {
|
|
340
|
+
log.catch(err);
|
|
341
|
+
}
|
|
315
342
|
}
|
|
316
343
|
|
|
317
344
|
log('closed', { peerId: this.ownId });
|
|
@@ -397,4 +424,11 @@ export class Connection {
|
|
|
397
424
|
this._state = state;
|
|
398
425
|
this.stateChanged.emit(state);
|
|
399
426
|
}
|
|
427
|
+
|
|
428
|
+
private async _emitTransportStats() {
|
|
429
|
+
const stats = await this.transport?.getStats();
|
|
430
|
+
if (stats) {
|
|
431
|
+
this.transportStats.emit(stats);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
400
434
|
}
|
|
@@ -10,6 +10,9 @@ import { log } from '@dxos/log';
|
|
|
10
10
|
|
|
11
11
|
import { type SwarmController, type Topology } from './topology';
|
|
12
12
|
|
|
13
|
+
const MIN_UPDATE_INTERVAL = 1000 * 10;
|
|
14
|
+
const MAX_CHANGES_PER_UPDATE = 1;
|
|
15
|
+
|
|
13
16
|
export interface MMSTTopologyOptions {
|
|
14
17
|
/**
|
|
15
18
|
* Number of connections the peer will originate by itself.
|
|
@@ -36,6 +39,8 @@ export class MMSTTopology implements Topology {
|
|
|
36
39
|
|
|
37
40
|
private _sampleCollected = false;
|
|
38
41
|
|
|
42
|
+
private _lastAction = new Date(0);
|
|
43
|
+
|
|
39
44
|
constructor({ originateConnections = 2, maxPeers = 4, sampleSize = 10 }: MMSTTopologyOptions = {}) {
|
|
40
45
|
this._originateConnections = originateConnections;
|
|
41
46
|
this._maxPeers = maxPeers;
|
|
@@ -74,22 +79,45 @@ export class MMSTTopology implements Topology {
|
|
|
74
79
|
invariant(this._controller, 'Not initialized');
|
|
75
80
|
const { connected, candidates, ownPeerId } = this._controller.getState();
|
|
76
81
|
|
|
82
|
+
// TODO(nf): does this rate limiting/flap dampening logic belong here or in the SwarmController?
|
|
77
83
|
if (connected.length > this._maxPeers) {
|
|
78
84
|
// Disconnect extra peers.
|
|
85
|
+
log(`disconnect ${connected.length - this._maxPeers} peers.`);
|
|
79
86
|
const sorted = sortByXorDistance(connected, ownPeerId)
|
|
80
87
|
.reverse()
|
|
81
88
|
.slice(0, this._maxPeers - connected.length);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
invariant(sorted.length === 0);
|
|
90
|
+
|
|
91
|
+
if (sorted.length > MAX_CHANGES_PER_UPDATE) {
|
|
92
|
+
log(`want to disconnect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {
|
|
96
|
+
for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {
|
|
97
|
+
log(`Disconnect ${peer}.`);
|
|
98
|
+
this._controller.disconnect(peer);
|
|
99
|
+
}
|
|
100
|
+
this._lastAction = new Date();
|
|
101
|
+
} else {
|
|
102
|
+
log('rate limited discconnect');
|
|
85
103
|
}
|
|
86
104
|
} else if (connected.length < this._originateConnections) {
|
|
87
105
|
// Connect new peers to reach desired quota.
|
|
106
|
+
log(`connect ${this._originateConnections - connected.length} peers.`);
|
|
88
107
|
const sample = candidates.sort(() => Math.random() - 0.5).slice(0, this._sampleSize);
|
|
89
108
|
const sorted = sortByXorDistance(sample, ownPeerId).slice(0, this._originateConnections - connected.length);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
109
|
+
|
|
110
|
+
if (sorted.length > MAX_CHANGES_PER_UPDATE) {
|
|
111
|
+
log(`want to connect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`);
|
|
112
|
+
}
|
|
113
|
+
if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {
|
|
114
|
+
for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {
|
|
115
|
+
log(`Connect ${peer}.`);
|
|
116
|
+
this._controller.connect(peer);
|
|
117
|
+
}
|
|
118
|
+
this._lastAction = new Date();
|
|
119
|
+
} else {
|
|
120
|
+
log('rate limited connect');
|
|
93
121
|
}
|
|
94
122
|
}
|
|
95
123
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import node from 'node-datachannel';
|
|
5
|
+
import node, { type SelectedCandidateInfo } from 'node-datachannel';
|
|
6
6
|
import defer, { type DeferredPromise } from 'p-defer';
|
|
7
7
|
|
|
8
8
|
import { DataChannel } from './rtc-data-channel';
|
|
@@ -45,21 +45,17 @@ export class PeerConnection extends EventTarget implements RTCPeerConnection {
|
|
|
45
45
|
const iceServers = init.iceServers ?? [];
|
|
46
46
|
|
|
47
47
|
this.#peerConnection = new node.PeerConnection(`peer-${Math.random()}`, {
|
|
48
|
+
// convert https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#iceservers to the format expected by https://github.com/murat-dogan/node-datachannel/blob/master/src/peer-connection-wrapper.cpp#L101
|
|
48
49
|
iceServers: iceServers
|
|
49
50
|
.map((server) => {
|
|
50
|
-
const urls =
|
|
51
|
+
const urls = Array.isArray(server.urls) ? server.urls : [server.urls];
|
|
51
52
|
|
|
52
53
|
return urls.map((url) => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
password: server.credential,
|
|
59
|
-
// relayType - how to specify?
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
return iceServer;
|
|
54
|
+
if (server.username && server.credential) {
|
|
55
|
+
const [protocol, rest] = url.split(/:(.*)/);
|
|
56
|
+
return `${protocol}:${server.username}:${server.credential}@${rest}`;
|
|
57
|
+
}
|
|
58
|
+
return url;
|
|
63
59
|
});
|
|
64
60
|
})
|
|
65
61
|
.flat(),
|
|
@@ -188,6 +184,10 @@ export class PeerConnection extends EventTarget implements RTCPeerConnection {
|
|
|
188
184
|
this.#peerConnection.addRemoteCandidate(candidate.candidate, candidate.sdpMid ?? '0');
|
|
189
185
|
}
|
|
190
186
|
|
|
187
|
+
getSelectedCandidatePair(): { local: SelectedCandidateInfo; remote: SelectedCandidateInfo } | null {
|
|
188
|
+
return this.#peerConnection.getSelectedCandidatePair();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
191
|
addTrack(track: MediaStreamTrack, ...streams: MediaStream[]): RTCRtpSender {
|
|
192
192
|
throw new Error('addTrack Not implemented');
|
|
193
193
|
}
|
|
@@ -206,6 +206,14 @@ export class PeerConnection extends EventTarget implements RTCPeerConnection {
|
|
|
206
206
|
this.#peerConnection.destroy();
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
+
bytesSent(): number {
|
|
210
|
+
return this.#peerConnection.bytesSent();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
bytesReceived(): number {
|
|
214
|
+
return this.#peerConnection.bytesReceived();
|
|
215
|
+
}
|
|
216
|
+
|
|
209
217
|
createDataChannel(label: string, dataChannelDict: RTCDataChannelInit = {}): RTCDataChannel {
|
|
210
218
|
const channel = this.#peerConnection.createDataChannel(label, dataChannelDict);
|
|
211
219
|
const dataChannel = new DataChannel(channel, dataChannelDict);
|
|
@@ -10,7 +10,7 @@ import { log } from '@dxos/log';
|
|
|
10
10
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
11
11
|
|
|
12
12
|
import { type PeerConnection } from './datachannel/rtc-peer-connection';
|
|
13
|
-
import { type Transport, type TransportFactory } from './transport';
|
|
13
|
+
import { type Transport, type TransportFactory, type TransportStats } from './transport';
|
|
14
14
|
|
|
15
15
|
export type LibDataChannelTransportParams = {
|
|
16
16
|
initiator: boolean;
|
|
@@ -126,14 +126,18 @@ export class LibDataChannelTransport implements Transport {
|
|
|
126
126
|
log.debug('dataChannel.onopen');
|
|
127
127
|
const duplex = new Duplex({
|
|
128
128
|
read: () => {},
|
|
129
|
-
write: (chunk, encoding, callback) => {
|
|
129
|
+
write: async (chunk, encoding, callback) => {
|
|
130
130
|
// todo wait to open
|
|
131
131
|
|
|
132
132
|
if (chunk.length > MAX_MESSAGE_SIZE) {
|
|
133
133
|
this.errors.raise(new Error(`message too large: ${chunk.length} > ${MAX_MESSAGE_SIZE}`));
|
|
134
134
|
}
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
try {
|
|
136
|
+
dataChannel.send(chunk);
|
|
137
|
+
} catch (err: any) {
|
|
138
|
+
this.errors.raise(err);
|
|
139
|
+
await this._close();
|
|
140
|
+
}
|
|
137
141
|
if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {
|
|
138
142
|
if (this._writeCallback !== null) {
|
|
139
143
|
log.error("consumer trying to write before we're ready for more data");
|
|
@@ -233,6 +237,42 @@ export class LibDataChannelTransport implements Transport {
|
|
|
233
237
|
});
|
|
234
238
|
}
|
|
235
239
|
|
|
240
|
+
async getDetails(): Promise<string> {
|
|
241
|
+
return this._peer
|
|
242
|
+
.then(async (peer) => {
|
|
243
|
+
const cp = await peer.getSelectedCandidatePair();
|
|
244
|
+
if (!cp) {
|
|
245
|
+
return 'unavailable';
|
|
246
|
+
}
|
|
247
|
+
return `${cp.remote.address}:${cp.remote.port}/${cp.remote.transportType} ${cp.remote.type}`;
|
|
248
|
+
})
|
|
249
|
+
.catch((err) => {
|
|
250
|
+
log.catch(err);
|
|
251
|
+
return 'unavailable';
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
async getStats(): Promise<TransportStats> {
|
|
256
|
+
return this._peer
|
|
257
|
+
.then((peer) => {
|
|
258
|
+
return {
|
|
259
|
+
bytesSent: peer.bytesSent(),
|
|
260
|
+
bytesReceived: peer.bytesReceived(),
|
|
261
|
+
packetsSent: 0,
|
|
262
|
+
packetsReceived: 0,
|
|
263
|
+
};
|
|
264
|
+
})
|
|
265
|
+
.catch((err) => {
|
|
266
|
+
log.catch(err);
|
|
267
|
+
return {
|
|
268
|
+
bytesSent: 0,
|
|
269
|
+
bytesReceived: 0,
|
|
270
|
+
packetsSent: 0,
|
|
271
|
+
packetsReceived: 0,
|
|
272
|
+
};
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
236
276
|
// TODO(nf): add classmethod to call node-datachannel.cleanup() when all instances have been destroyed?
|
|
237
277
|
async destroy(): Promise<void> {
|
|
238
278
|
await this._close();
|
|
@@ -12,7 +12,7 @@ import { log, logInfo } from '@dxos/log';
|
|
|
12
12
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
13
13
|
import { ComplexMap } from '@dxos/util';
|
|
14
14
|
|
|
15
|
-
import { type Transport, type TransportFactory, type TransportOptions } from './transport';
|
|
15
|
+
import { type Transport, type TransportFactory, type TransportOptions, type TransportStats } from './transport';
|
|
16
16
|
|
|
17
17
|
// TODO(burdon): Make configurable.
|
|
18
18
|
// Delay (in milliseconds) for data being sent through in-memory connections to simulate network latency.
|
|
@@ -166,4 +166,17 @@ export class MemoryTransport implements Transport {
|
|
|
166
166
|
this._remote.wake(remoteId);
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
+
|
|
170
|
+
async getDetails(): Promise<string> {
|
|
171
|
+
return this._instanceId.toHex();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async getStats(): Promise<TransportStats> {
|
|
175
|
+
return {
|
|
176
|
+
bytesSent: 0,
|
|
177
|
+
bytesReceived: 0,
|
|
178
|
+
packetsSent: 0,
|
|
179
|
+
packetsReceived: 0,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
169
182
|
}
|