@dxos/network-manager 0.6.12-staging.e11e696 → 0.6.12
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-YOKKEU6T.mjs → chunk-XYSYUN63.mjs} +998 -1192
- package/dist/lib/browser/chunk-XYSYUN63.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +19 -10
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +27 -18
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-7ZWQLO5T.cjs → chunk-4YAYC7WN.cjs} +1166 -1233
- package/dist/lib/node/chunk-4YAYC7WN.cjs.map +7 -0
- package/dist/lib/node/index.cjs +37 -27
- package/dist/lib/node/index.cjs.map +2 -2
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +29 -20
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/types/src/signal/integration.test.d.ts +2 -0
- package/dist/types/src/signal/integration.test.d.ts.map +1 -0
- package/dist/types/src/signal/swarm-messenger.test.d.ts +2 -0
- package/dist/types/src/signal/swarm-messenger.test.d.ts.map +1 -0
- package/dist/types/src/swarm/connection.d.ts.map +1 -1
- package/dist/types/src/swarm/swarm.d.ts +1 -1
- package/dist/types/src/testing/test-builder.d.ts +2 -2
- package/dist/types/src/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/tests/basic-test-suite.d.ts.map +1 -1
- package/dist/types/src/tests/property-test-suite.d.ts.map +1 -1
- package/dist/types/src/tests/tcp-transport.test.d.ts +2 -0
- package/dist/types/src/tests/tcp-transport.test.d.ts.map +1 -0
- package/dist/types/src/tests/utils.d.ts.map +1 -1
- package/dist/types/src/transport/index.d.ts +5 -1
- package/dist/types/src/transport/index.d.ts.map +1 -1
- package/dist/types/src/transport/libdatachannel-transport.d.ts +42 -0
- package/dist/types/src/transport/libdatachannel-transport.d.ts.map +1 -0
- package/dist/types/src/transport/libdatachannel-transport.test.d.ts +2 -0
- package/dist/types/src/transport/libdatachannel-transport.test.d.ts.map +1 -0
- package/dist/types/src/transport/memory-transport.d.ts +2 -2
- package/dist/types/src/transport/memory-transport.d.ts.map +1 -1
- package/dist/types/src/transport/memory-transport.test.d.ts +2 -0
- package/dist/types/src/transport/memory-transport.test.d.ts.map +1 -0
- package/dist/types/src/transport/simplepeer-simple-peer.d.ts +2 -0
- package/dist/types/src/transport/simplepeer-simple-peer.d.ts.map +1 -0
- package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts +2 -0
- package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts.map +1 -0
- package/dist/types/src/transport/{webrtc/rtc-transport-proxy.d.ts → simplepeer-transport-proxy.d.ts} +12 -10
- package/dist/types/src/transport/simplepeer-transport-proxy.d.ts.map +1 -0
- package/dist/types/src/transport/{webrtc/rtc-transport-service.d.ts → simplepeer-transport-service.d.ts} +7 -9
- package/dist/types/src/transport/simplepeer-transport-service.d.ts.map +1 -0
- package/dist/types/src/transport/simplepeer-transport.d.ts +36 -0
- package/dist/types/src/transport/simplepeer-transport.d.ts.map +1 -0
- package/dist/types/src/transport/simplepeer-transport.test.d.ts +2 -0
- package/dist/types/src/transport/simplepeer-transport.test.d.ts.map +1 -0
- package/dist/types/src/transport/{tcp/tcp-transport.browser.d.ts → tcp-transport.browser.d.ts} +3 -3
- package/dist/types/src/transport/tcp-transport.browser.d.ts.map +1 -0
- package/dist/types/src/transport/{tcp/tcp-transport.d.ts → tcp-transport.d.ts} +3 -3
- package/dist/types/src/transport/tcp-transport.d.ts.map +1 -0
- package/dist/types/src/transport/transport.d.ts +6 -7
- package/dist/types/src/transport/transport.d.ts.map +1 -1
- package/dist/types/src/transport/webrtc.d.ts +6 -0
- package/dist/types/src/transport/webrtc.d.ts.map +1 -0
- package/package.json +30 -53
- package/src/globals.d.ts +7 -0
- package/src/signal/ice.test.ts +3 -1
- package/src/signal/{integration.node.test.ts → integration.test.ts} +15 -9
- package/src/signal/{swarm-messenger.node.test.ts → swarm-messenger.test.ts} +23 -13
- package/src/swarm/connection-limiter.test.ts +6 -3
- package/src/swarm/connection.test.ts +38 -63
- package/src/swarm/connection.ts +5 -5
- package/src/swarm/swarm.test.ts +11 -9
- package/src/swarm/swarm.ts +1 -1
- package/src/testing/test-builder.ts +28 -12
- package/src/tests/basic-test-suite.ts +33 -34
- package/src/tests/memory-transport.test.ts +42 -40
- package/src/tests/property-test-suite.ts +22 -21
- package/src/tests/tcp-transport.test.ts +67 -0
- package/src/tests/utils.ts +2 -3
- package/src/tests/webrtc-transport.test.ts +9 -9
- package/src/transport/index.ts +5 -1
- package/src/transport/libdatachannel-transport.test.ts +100 -0
- package/src/transport/libdatachannel-transport.ts +376 -0
- package/src/transport/memory-transport.test.ts +74 -0
- package/src/transport/memory-transport.ts +0 -2
- package/src/transport/simplepeer-simple-peer.ts +26 -0
- package/src/transport/simplepeer-transport-proxy-test.ts +181 -0
- package/src/transport/simplepeer-transport-proxy.ts +246 -0
- package/src/transport/simplepeer-transport-service.ts +160 -0
- package/src/transport/simplepeer-transport.test.ts +61 -0
- package/src/transport/simplepeer-transport.ts +250 -0
- package/src/transport/{tcp/tcp-transport.browser.ts → tcp-transport.browser.ts} +3 -7
- package/src/transport/{tcp/tcp-transport.ts → tcp-transport.ts} +1 -3
- package/src/transport/transport.ts +7 -8
- package/src/transport/webrtc.ts +15 -0
- package/src/typings.d.ts +2 -8
- package/dist/lib/browser/chunk-GW3YM55A.mjs +0 -14
- package/dist/lib/browser/chunk-GW3YM55A.mjs.map +0 -7
- package/dist/lib/browser/chunk-YOKKEU6T.mjs.map +0 -7
- package/dist/lib/browser/transport/tcp/index.mjs +0 -39
- package/dist/lib/browser/transport/tcp/index.mjs.map +0 -7
- package/dist/lib/node/chunk-7ZWQLO5T.cjs.map +0 -7
- package/dist/lib/node/transport/tcp/index.cjs +0 -191
- package/dist/lib/node/transport/tcp/index.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-4VO725JT.mjs +0 -4383
- package/dist/lib/node-esm/chunk-4VO725JT.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -50
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/testing/index.mjs +0 -280
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- package/dist/lib/node-esm/transport/tcp/index.mjs +0 -159
- package/dist/lib/node-esm/transport/tcp/index.mjs.map +0 -7
- package/dist/types/src/signal/integration.node.test.d.ts +0 -2
- package/dist/types/src/signal/integration.node.test.d.ts.map +0 -1
- package/dist/types/src/signal/swarm-messenger.node.test.d.ts +0 -2
- package/dist/types/src/signal/swarm-messenger.node.test.d.ts.map +0 -1
- package/dist/types/src/tests/tcp-transport.node.test.d.ts +0 -2
- package/dist/types/src/tests/tcp-transport.node.test.d.ts.map +0 -1
- package/dist/types/src/transport/tcp/index.d.ts +0 -2
- package/dist/types/src/transport/tcp/index.d.ts.map +0 -1
- package/dist/types/src/transport/tcp/tcp-transport.browser.d.ts.map +0 -1
- package/dist/types/src/transport/tcp/tcp-transport.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/index.d.ts +0 -4
- package/dist/types/src/transport/webrtc/index.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts +0 -14
- package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts +0 -68
- package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts +0 -33
- package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts +0 -2
- package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts +0 -4
- package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/rtc-transport-proxy.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts +0 -2
- package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/rtc-transport-service.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts +0 -4
- package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts +0 -2
- package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/test-utils.d.ts +0 -5
- package/dist/types/src/transport/webrtc/test-utils.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc/utils.d.ts +0 -3
- package/dist/types/src/transport/webrtc/utils.d.ts.map +0 -1
- package/src/tests/tcp-transport.node.test.ts +0 -65
- package/src/transport/tcp/index.ts +0 -5
- package/src/transport/webrtc/index.ts +0 -7
- package/src/transport/webrtc/rtc-connection-factory.ts +0 -82
- package/src/transport/webrtc/rtc-peer-connection.ts +0 -472
- package/src/transport/webrtc/rtc-transport-channel.test.ts +0 -176
- package/src/transport/webrtc/rtc-transport-channel.ts +0 -195
- package/src/transport/webrtc/rtc-transport-factory.ts +0 -28
- package/src/transport/webrtc/rtc-transport-proxy.test.ts +0 -413
- package/src/transport/webrtc/rtc-transport-proxy.ts +0 -264
- package/src/transport/webrtc/rtc-transport-service.ts +0 -192
- package/src/transport/webrtc/rtc-transport-stats.ts +0 -67
- package/src/transport/webrtc/rtc-transport.test.ts +0 -198
- package/src/transport/webrtc/test-utils.ts +0 -22
- package/src/transport/webrtc/utils.ts +0 -36
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import "@dxos/node-std/globals";
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
// inject-globals:@inject-globals
|
|
2
10
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
11
|
+
global,
|
|
12
|
+
Buffer as Buffer2,
|
|
13
|
+
process
|
|
14
|
+
} from "@dxos/node-std/inject-globals";
|
|
5
15
|
|
|
6
16
|
// packages/core/mesh/network-manager/src/swarm/connection.ts
|
|
7
17
|
import { DeferredTask, Event, sleep, scheduleTask, scheduleTaskInterval, synchronized, Trigger } from "@dxos/async";
|
|
@@ -10,7 +20,7 @@ import { ErrorStream } from "@dxos/debug";
|
|
|
10
20
|
import { invariant } from "@dxos/invariant";
|
|
11
21
|
import { PublicKey } from "@dxos/keys";
|
|
12
22
|
import { log, logInfo } from "@dxos/log";
|
|
13
|
-
import { CancelledError, ProtocolError, ConnectionResetError, ConnectivityError, TimeoutError, trace } from "@dxos/protocols";
|
|
23
|
+
import { CancelledError, ProtocolError, ConnectionResetError, ConnectivityError, TimeoutError, UnknownProtocolError, trace } from "@dxos/protocols";
|
|
14
24
|
function _ts_decorate(decorators, target, key, desc) {
|
|
15
25
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
16
26
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -46,11 +56,11 @@ var Connection = class {
|
|
|
46
56
|
this._callbacks = _callbacks;
|
|
47
57
|
this._ctx = new Context(void 0, {
|
|
48
58
|
F: __dxlog_file,
|
|
49
|
-
L:
|
|
59
|
+
L: 101
|
|
50
60
|
});
|
|
51
61
|
this.connectedTimeoutContext = new Context(void 0, {
|
|
52
62
|
F: __dxlog_file,
|
|
53
|
-
L:
|
|
63
|
+
L: 102
|
|
54
64
|
});
|
|
55
65
|
this._protocolClosed = new Trigger();
|
|
56
66
|
this._transportClosed = new Trigger();
|
|
@@ -73,7 +83,7 @@ var Connection = class {
|
|
|
73
83
|
initiator: this.initiator
|
|
74
84
|
}, {
|
|
75
85
|
F: __dxlog_file,
|
|
76
|
-
L:
|
|
86
|
+
L: 138,
|
|
77
87
|
S: this,
|
|
78
88
|
C: (f, a) => f(...a)
|
|
79
89
|
});
|
|
@@ -96,7 +106,7 @@ var Connection = class {
|
|
|
96
106
|
async openConnection() {
|
|
97
107
|
invariant(this._state === "INITIAL", "Invalid state.", {
|
|
98
108
|
F: __dxlog_file,
|
|
99
|
-
L:
|
|
109
|
+
L: 168,
|
|
100
110
|
S: this,
|
|
101
111
|
A: [
|
|
102
112
|
"this._state === ConnectionState.INITIAL",
|
|
@@ -107,7 +117,7 @@ var Connection = class {
|
|
|
107
117
|
id: this._instanceId
|
|
108
118
|
}), {
|
|
109
119
|
F: __dxlog_file,
|
|
110
|
-
L:
|
|
120
|
+
L: 169,
|
|
111
121
|
S: this,
|
|
112
122
|
C: (f, a) => f(...a)
|
|
113
123
|
});
|
|
@@ -119,7 +129,7 @@ var Connection = class {
|
|
|
119
129
|
initiator: this.initiator
|
|
120
130
|
}, {
|
|
121
131
|
F: __dxlog_file,
|
|
122
|
-
L:
|
|
132
|
+
L: 170,
|
|
123
133
|
S: this,
|
|
124
134
|
C: (f, a) => f(...a)
|
|
125
135
|
});
|
|
@@ -130,7 +140,7 @@ var Connection = class {
|
|
|
130
140
|
this._protocol.stream.on("close", () => {
|
|
131
141
|
log("protocol stream closed", void 0, {
|
|
132
142
|
F: __dxlog_file,
|
|
133
|
-
L:
|
|
143
|
+
L: 187,
|
|
134
144
|
S: this,
|
|
135
145
|
C: (f, a) => f(...a)
|
|
136
146
|
});
|
|
@@ -140,7 +150,7 @@ var Connection = class {
|
|
|
140
150
|
scheduleTask(this.connectedTimeoutContext, async () => {
|
|
141
151
|
log.info(`timeout waiting ${TRANSPORT_CONNECTION_TIMEOUT / 1e3}s for transport to connect, aborting`, void 0, {
|
|
142
152
|
F: __dxlog_file,
|
|
143
|
-
L:
|
|
153
|
+
L: 195,
|
|
144
154
|
S: this,
|
|
145
155
|
C: (f, a) => f(...a)
|
|
146
156
|
});
|
|
@@ -148,7 +158,7 @@ var Connection = class {
|
|
|
148
158
|
}, TRANSPORT_CONNECTION_TIMEOUT);
|
|
149
159
|
invariant(!this._transport, void 0, {
|
|
150
160
|
F: __dxlog_file,
|
|
151
|
-
L:
|
|
161
|
+
L: 203,
|
|
152
162
|
S: this,
|
|
153
163
|
A: [
|
|
154
164
|
"!this._transport",
|
|
@@ -156,14 +166,12 @@ var Connection = class {
|
|
|
156
166
|
]
|
|
157
167
|
});
|
|
158
168
|
this._transport = this._transportFactory.createTransport({
|
|
159
|
-
ownPeerKey: this.localInfo.peerKey,
|
|
160
|
-
remotePeerKey: this.remoteInfo.peerKey,
|
|
161
|
-
topic: this.topic.toHex(),
|
|
162
169
|
initiator: this.initiator,
|
|
163
170
|
stream: this._protocol.stream,
|
|
164
171
|
sendSignal: async (signal) => this._sendSignal(signal),
|
|
165
172
|
sessionId: this.sessionId
|
|
166
173
|
});
|
|
174
|
+
await this._transport.open();
|
|
167
175
|
this._transport.connected.once(async () => {
|
|
168
176
|
this._changeState("CONNECTED");
|
|
169
177
|
await this.connectedTimeoutContext.dispose();
|
|
@@ -209,13 +217,21 @@ var Connection = class {
|
|
|
209
217
|
C: (f, a) => f(...a)
|
|
210
218
|
});
|
|
211
219
|
this.abort().catch((err2) => this.errors.raise(err2));
|
|
220
|
+
} else if (err instanceof UnknownProtocolError) {
|
|
221
|
+
log.warn("unsure what to do with UnknownProtocolError, will keep on truckin", {
|
|
222
|
+
err
|
|
223
|
+
}, {
|
|
224
|
+
F: __dxlog_file,
|
|
225
|
+
L: 242,
|
|
226
|
+
S: this,
|
|
227
|
+
C: (f, a) => f(...a)
|
|
228
|
+
});
|
|
212
229
|
}
|
|
213
230
|
if (this._state !== "CLOSED" && this._state !== "CLOSING") {
|
|
214
231
|
await this.connectedTimeoutContext.dispose();
|
|
215
232
|
this.errors.raise(err);
|
|
216
233
|
}
|
|
217
234
|
});
|
|
218
|
-
await this._transport.open();
|
|
219
235
|
for (const signal of this._incomingSignalBuffer) {
|
|
220
236
|
void this._transport.onSignal(signal);
|
|
221
237
|
}
|
|
@@ -2614,7 +2630,7 @@ var sortByXorDistance = (keys, reference) => {
|
|
|
2614
2630
|
};
|
|
2615
2631
|
var distXor = (a, b) => {
|
|
2616
2632
|
const maxLength = Math.max(a.length, b.length);
|
|
2617
|
-
const result =
|
|
2633
|
+
const result = Buffer2.allocUnsafe(maxLength);
|
|
2618
2634
|
for (let i = 0; i < maxLength; i++) {
|
|
2619
2635
|
result[i] = (a[i] || 0) ^ (b[i] || 0);
|
|
2620
2636
|
}
|
|
@@ -2849,12 +2865,11 @@ var MemoryTransport = class _MemoryTransport {
|
|
|
2849
2865
|
this.errors.raise(err);
|
|
2850
2866
|
});
|
|
2851
2867
|
}
|
|
2852
|
-
return this;
|
|
2853
2868
|
}
|
|
2854
2869
|
async close() {
|
|
2855
2870
|
log11("closing...", void 0, {
|
|
2856
2871
|
F: __dxlog_file12,
|
|
2857
|
-
L:
|
|
2872
|
+
L: 129,
|
|
2858
2873
|
S: this,
|
|
2859
2874
|
C: (f, a) => f(...a)
|
|
2860
2875
|
});
|
|
@@ -2875,18 +2890,17 @@ var MemoryTransport = class _MemoryTransport {
|
|
|
2875
2890
|
this.closed.emit();
|
|
2876
2891
|
log11("closed", void 0, {
|
|
2877
2892
|
F: __dxlog_file12,
|
|
2878
|
-
L:
|
|
2893
|
+
L: 157,
|
|
2879
2894
|
S: this,
|
|
2880
2895
|
C: (f, a) => f(...a)
|
|
2881
2896
|
});
|
|
2882
|
-
return this;
|
|
2883
2897
|
}
|
|
2884
2898
|
async onSignal({ payload }) {
|
|
2885
2899
|
log11("received signal", {
|
|
2886
2900
|
payload
|
|
2887
2901
|
}, {
|
|
2888
2902
|
F: __dxlog_file12,
|
|
2889
|
-
L:
|
|
2903
|
+
L: 161,
|
|
2890
2904
|
S: this,
|
|
2891
2905
|
C: (f, a) => f(...a)
|
|
2892
2906
|
});
|
|
@@ -2922,1018 +2936,550 @@ var toError = (err) => err instanceof Error ? err : new Error(String(err));
|
|
|
2922
2936
|
// packages/core/mesh/network-manager/src/transport/transport.ts
|
|
2923
2937
|
var TransportKind;
|
|
2924
2938
|
(function(TransportKind2) {
|
|
2925
|
-
TransportKind2["
|
|
2926
|
-
TransportKind2["
|
|
2939
|
+
TransportKind2["SIMPLE_PEER"] = "SIMPLE_PEER";
|
|
2940
|
+
TransportKind2["SIMPLE_PEER_PROXY"] = "SIMPLE_PEER_PROXY";
|
|
2941
|
+
TransportKind2["LIBDATACHANNEL"] = "LIBDATACHANNEL";
|
|
2927
2942
|
TransportKind2["MEMORY"] = "MEMORY";
|
|
2928
2943
|
TransportKind2["TCP"] = "TCP";
|
|
2929
2944
|
})(TransportKind || (TransportKind = {}));
|
|
2930
2945
|
|
|
2931
|
-
// packages/core/mesh/network-manager/src/transport/
|
|
2932
|
-
import
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
}
|
|
2938
|
-
async createConnection(config) {
|
|
2939
|
-
return new RTCPeerConnection(config);
|
|
2940
|
-
}
|
|
2941
|
-
async initConnection(connection, info) {
|
|
2942
|
-
}
|
|
2943
|
-
};
|
|
2944
|
-
var NodeRtcConnectionFactory = class _NodeRtcConnectionFactory {
|
|
2945
|
-
static {
|
|
2946
|
-
this._createdConnections = 0;
|
|
2947
|
-
}
|
|
2948
|
-
static {
|
|
2949
|
-
this._cleanupMutex = new Mutex();
|
|
2950
|
-
}
|
|
2951
|
-
// This should be inside the function to avoid triggering `eval` in the global scope.
|
|
2952
|
-
// eslint-disable-next-line no-new-func
|
|
2953
|
-
// TODO(burdon): Do imports here?
|
|
2954
|
-
async initialize() {
|
|
2955
|
-
}
|
|
2956
|
-
async onConnectionDestroyed() {
|
|
2957
|
-
return _NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
|
|
2958
|
-
if (--_NodeRtcConnectionFactory._createdConnections === 0) {
|
|
2959
|
-
(await import("#node-datachannel")).cleanup();
|
|
2960
|
-
}
|
|
2961
|
-
});
|
|
2962
|
-
}
|
|
2963
|
-
async createConnection(config) {
|
|
2964
|
-
return _NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
|
|
2965
|
-
const { RTCPeerConnection: RTCPeerConnection1 } = await import("#node-datachannel/polyfill");
|
|
2966
|
-
_NodeRtcConnectionFactory._createdConnections++;
|
|
2967
|
-
return new RTCPeerConnection1(config);
|
|
2968
|
-
});
|
|
2969
|
-
}
|
|
2970
|
-
async initConnection(connection, info) {
|
|
2971
|
-
if (info.initiator) {
|
|
2972
|
-
connection.onnegotiationneeded?.(null);
|
|
2973
|
-
}
|
|
2974
|
-
}
|
|
2975
|
-
};
|
|
2976
|
-
var getRtcConnectionFactory = () => {
|
|
2977
|
-
return typeof globalThis.RTCPeerConnection === "undefined" ? new NodeRtcConnectionFactory() : new BrowserRtcConnectionFactory();
|
|
2978
|
-
};
|
|
2979
|
-
|
|
2980
|
-
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-peer-connection.ts
|
|
2981
|
-
import { synchronized as synchronized5, Trigger as Trigger3, Mutex as Mutex2 } from "@dxos/async";
|
|
2982
|
-
import { invariant as invariant12 } from "@dxos/invariant";
|
|
2983
|
-
import { log as log13, logInfo as logInfo4 } from "@dxos/log";
|
|
2984
|
-
import { ConnectivityError as ConnectivityError3 } from "@dxos/protocols";
|
|
2985
|
-
import { trace as trace4 } from "@dxos/tracing";
|
|
2986
|
-
|
|
2987
|
-
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-channel.ts
|
|
2988
|
-
import { Duplex } from "@dxos/node-std/stream";
|
|
2989
|
-
import { Event as AsyncEvent } from "@dxos/async";
|
|
2990
|
-
import { Resource } from "@dxos/context";
|
|
2991
|
-
import { ErrorStream as ErrorStream4 } from "@dxos/debug";
|
|
2992
|
-
import { invariant as invariant11 } from "@dxos/invariant";
|
|
2946
|
+
// packages/core/mesh/network-manager/src/transport/simplepeer-transport.ts
|
|
2947
|
+
import SimplePeerConstructor from "simple-peer";
|
|
2948
|
+
import invariant11 from "tiny-invariant";
|
|
2949
|
+
import { Event as Event8, synchronized as synchronized5 } from "@dxos/async";
|
|
2950
|
+
import { ErrorStream as ErrorStream4, raise as raise2 } from "@dxos/debug";
|
|
2951
|
+
import { PublicKey as PublicKey10 } from "@dxos/keys";
|
|
2993
2952
|
import { log as log12 } from "@dxos/log";
|
|
2994
|
-
import { ConnectivityError as ConnectivityError2 } from "@dxos/protocols";
|
|
2953
|
+
import { ConnectionResetError as ConnectionResetError2, ConnectivityError as ConnectivityError2, ProtocolError as ProtocolError2, UnknownProtocolError as UnknownProtocolError2, trace as trace4 } from "@dxos/protocols";
|
|
2954
|
+
|
|
2955
|
+
// packages/core/mesh/network-manager/src/transport/webrtc.ts
|
|
2956
|
+
var wrtc = null;
|
|
2957
|
+
try {
|
|
2958
|
+
wrtc = __require("@koush/wrtc");
|
|
2959
|
+
} catch {
|
|
2960
|
+
}
|
|
2995
2961
|
|
|
2996
|
-
// packages/core/mesh/network-manager/src/transport/
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
if (
|
|
3001
|
-
|
|
2962
|
+
// packages/core/mesh/network-manager/src/transport/simplepeer-transport.ts
|
|
2963
|
+
function _ts_decorate6(decorators, target, key, desc) {
|
|
2964
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2965
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2966
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2967
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2968
|
+
}
|
|
2969
|
+
var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/simplepeer-transport.ts";
|
|
2970
|
+
var createSimplePeerTransportFactory = (webrtcConfig, iceProvider) => ({
|
|
2971
|
+
createTransport: (options) => new SimplePeerTransport({
|
|
2972
|
+
...options,
|
|
2973
|
+
webrtcConfig,
|
|
2974
|
+
iceProvider
|
|
2975
|
+
})
|
|
2976
|
+
});
|
|
2977
|
+
var SimplePeerTransport = class {
|
|
2978
|
+
get isOpen() {
|
|
2979
|
+
return this._piped && !this._closed;
|
|
3002
2980
|
}
|
|
3003
|
-
|
|
3004
|
-
|
|
2981
|
+
/**
|
|
2982
|
+
* @params opts.config formatted as per https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection
|
|
2983
|
+
*/
|
|
2984
|
+
constructor(_params) {
|
|
2985
|
+
this._params = _params;
|
|
2986
|
+
this._peer = void 0;
|
|
2987
|
+
this._closed = false;
|
|
2988
|
+
this._piped = false;
|
|
2989
|
+
this.closed = new Event8();
|
|
2990
|
+
this.connected = new Event8();
|
|
2991
|
+
this.errors = new ErrorStream4();
|
|
2992
|
+
this._instanceId = PublicKey10.random().toHex();
|
|
3005
2993
|
}
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
2994
|
+
async getStats() {
|
|
2995
|
+
const stats = await this._getStats();
|
|
2996
|
+
if (!stats) {
|
|
2997
|
+
return {
|
|
2998
|
+
bytesSent: 0,
|
|
2999
|
+
bytesReceived: 0,
|
|
3000
|
+
packetsSent: 0,
|
|
3001
|
+
packetsReceived: 0,
|
|
3002
|
+
rawStats: {}
|
|
3003
|
+
};
|
|
3004
|
+
}
|
|
3011
3005
|
return {
|
|
3012
|
-
bytesSent:
|
|
3013
|
-
bytesReceived:
|
|
3014
|
-
packetsSent:
|
|
3015
|
-
packetsReceived:
|
|
3016
|
-
rawStats:
|
|
3006
|
+
bytesSent: stats.transport.bytesSent,
|
|
3007
|
+
bytesReceived: stats.transport.bytesReceived,
|
|
3008
|
+
packetsSent: stats.transport.packetsSent,
|
|
3009
|
+
packetsReceived: stats.transport.packetsReceived,
|
|
3010
|
+
rawStats: stats.raw
|
|
3017
3011
|
};
|
|
3018
3012
|
}
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
};
|
|
3042
|
-
|
|
3043
|
-
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-channel.ts
|
|
3044
|
-
var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-channel.ts";
|
|
3045
|
-
var MAX_MESSAGE_SIZE = 64 * 1024;
|
|
3046
|
-
var MAX_BUFFERED_AMOUNT = 64 * 1024;
|
|
3047
|
-
var RtcTransportChannel = class extends Resource {
|
|
3048
|
-
constructor(_connection, _options) {
|
|
3049
|
-
super();
|
|
3050
|
-
this._connection = _connection;
|
|
3051
|
-
this._options = _options;
|
|
3052
|
-
this.closed = new AsyncEvent();
|
|
3053
|
-
this.connected = new AsyncEvent();
|
|
3054
|
-
this.errors = new ErrorStream4();
|
|
3055
|
-
this._streamDataFlushedCallback = null;
|
|
3056
|
-
this._isChannelCreationInProgress = false;
|
|
3057
|
-
}
|
|
3058
|
-
get isRtcChannelCreationInProgress() {
|
|
3059
|
-
return this._isChannelCreationInProgress;
|
|
3013
|
+
async _getStats() {
|
|
3014
|
+
if (typeof this._peer?._pc?.getStats !== "function") {
|
|
3015
|
+
return null;
|
|
3016
|
+
}
|
|
3017
|
+
return await this._peer._pc.getStats().then((stats) => {
|
|
3018
|
+
const statsEntries = Array.from(stats.entries());
|
|
3019
|
+
const transport = statsEntries.filter((s) => s[1].type === "transport")[0][1];
|
|
3020
|
+
const candidatePair = statsEntries.filter((s) => s[0] === transport.selectedCandidatePairId);
|
|
3021
|
+
let selectedCandidatePair;
|
|
3022
|
+
let remoteCandidate;
|
|
3023
|
+
if (candidatePair.length > 0) {
|
|
3024
|
+
selectedCandidatePair = candidatePair[0][1];
|
|
3025
|
+
remoteCandidate = statsEntries.filter((s) => s[0] === selectedCandidatePair.remoteCandidateId)[0][1];
|
|
3026
|
+
}
|
|
3027
|
+
return {
|
|
3028
|
+
datachannel: statsEntries.filter((s) => s[1].type === "data-channel")[0][1],
|
|
3029
|
+
transport,
|
|
3030
|
+
selectedCandidatePair,
|
|
3031
|
+
remoteCandidate,
|
|
3032
|
+
raw: Object.fromEntries(stats.entries())
|
|
3033
|
+
};
|
|
3034
|
+
});
|
|
3060
3035
|
}
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3036
|
+
async getDetails() {
|
|
3037
|
+
const stats = await this._getStats();
|
|
3038
|
+
const rc = stats?.remoteCandidate;
|
|
3039
|
+
if (!rc) {
|
|
3040
|
+
return "unavailable";
|
|
3064
3041
|
}
|
|
3042
|
+
if (rc.candidateType === "relay") {
|
|
3043
|
+
return `${rc.ip}:${rc.port}/${rc.protocol} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
|
|
3044
|
+
}
|
|
3045
|
+
return `${rc.ip}:${rc.port}/${rc.protocol} ${rc.candidateType}`;
|
|
3065
3046
|
}
|
|
3066
|
-
async
|
|
3067
|
-
|
|
3047
|
+
async open() {
|
|
3048
|
+
log12.trace("dxos.mesh.webrtc-transport.open", trace4.begin({
|
|
3049
|
+
id: this._instanceId
|
|
3050
|
+
}), {
|
|
3068
3051
|
F: __dxlog_file13,
|
|
3069
|
-
L:
|
|
3052
|
+
L: 122,
|
|
3070
3053
|
S: this,
|
|
3071
|
-
|
|
3072
|
-
"!this._isChannelCreationInProgress",
|
|
3073
|
-
""
|
|
3074
|
-
]
|
|
3075
|
-
});
|
|
3076
|
-
this._isChannelCreationInProgress = true;
|
|
3077
|
-
this._connection.createDataChannel(this._options.topic).then((channel) => {
|
|
3078
|
-
if (this.isOpen) {
|
|
3079
|
-
this._channel = channel;
|
|
3080
|
-
this._initChannel(this._channel);
|
|
3081
|
-
} else {
|
|
3082
|
-
this._safeCloseChannel(channel);
|
|
3083
|
-
}
|
|
3084
|
-
}).catch((err) => {
|
|
3085
|
-
if (this.isOpen) {
|
|
3086
|
-
this.errors.raise(new ConnectivityError2(`Failed to create a channel: ${err?.message ?? "unknown reason."}`));
|
|
3087
|
-
}
|
|
3088
|
-
}).finally(() => {
|
|
3089
|
-
this._isChannelCreationInProgress = false;
|
|
3054
|
+
C: (f, a) => f(...a)
|
|
3090
3055
|
});
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
this._safeCloseChannel(this._channel);
|
|
3095
|
-
this._channel = void 0;
|
|
3096
|
-
this._stream = void 0;
|
|
3097
|
-
}
|
|
3098
|
-
this.closed.emit();
|
|
3099
|
-
log12("closed", void 0, {
|
|
3056
|
+
log12("created connection", {
|
|
3057
|
+
params: this._params
|
|
3058
|
+
}, {
|
|
3100
3059
|
F: __dxlog_file13,
|
|
3101
|
-
L:
|
|
3060
|
+
L: 123,
|
|
3102
3061
|
S: this,
|
|
3103
3062
|
C: (f, a) => f(...a)
|
|
3104
3063
|
});
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3064
|
+
const providedIceServers = await this._params.iceProvider?.getIceServers();
|
|
3065
|
+
if (!this._params.webrtcConfig) {
|
|
3066
|
+
this._params.webrtcConfig = {};
|
|
3067
|
+
}
|
|
3068
|
+
this._params.webrtcConfig.iceServers = [
|
|
3069
|
+
...this._params.webrtcConfig.iceServers ?? [],
|
|
3070
|
+
...providedIceServers ?? []
|
|
3071
|
+
];
|
|
3072
|
+
this._peer = new SimplePeerConstructor({
|
|
3073
|
+
channelName: "dxos.mesh.transport",
|
|
3074
|
+
initiator: this._params.initiator,
|
|
3075
|
+
wrtc: SimplePeerConstructor.WEBRTC_SUPPORT ? void 0 : wrtc ?? raise2(new Error("wrtc not available")),
|
|
3076
|
+
config: this._params.webrtcConfig
|
|
3077
|
+
});
|
|
3078
|
+
this._peer.on("signal", async (data) => {
|
|
3079
|
+
log12("signal", data, {
|
|
3080
|
+
F: __dxlog_file13,
|
|
3081
|
+
L: 142,
|
|
3082
|
+
S: this,
|
|
3083
|
+
C: (f, a) => f(...a)
|
|
3084
|
+
});
|
|
3085
|
+
await this._params.sendSignal({
|
|
3086
|
+
payload: {
|
|
3087
|
+
data
|
|
3088
|
+
}
|
|
3089
|
+
});
|
|
3090
|
+
});
|
|
3091
|
+
this._peer.on("connect", () => {
|
|
3092
|
+
log12("connected", void 0, {
|
|
3093
|
+
F: __dxlog_file13,
|
|
3094
|
+
L: 147,
|
|
3095
|
+
S: this,
|
|
3096
|
+
C: (f, a) => f(...a)
|
|
3097
|
+
});
|
|
3098
|
+
this._params.stream.pipe(this._peer).pipe(this._params.stream);
|
|
3099
|
+
this._piped = true;
|
|
3100
|
+
this.connected.emit();
|
|
3101
|
+
});
|
|
3102
|
+
this._peer.on("close", async () => {
|
|
3103
|
+
log12("closed", void 0, {
|
|
3104
|
+
F: __dxlog_file13,
|
|
3105
|
+
L: 154,
|
|
3106
|
+
S: this,
|
|
3107
|
+
C: (f, a) => f(...a)
|
|
3108
|
+
});
|
|
3109
|
+
await this.close();
|
|
3110
|
+
});
|
|
3111
|
+
this._peer.on("error", async (err) => {
|
|
3112
|
+
if (typeof RTCError !== "undefined" && err instanceof RTCError) {
|
|
3113
|
+
if (err.errorDetail === "sctp-failure") {
|
|
3114
|
+
this.errors.raise(new ConnectionResetError2("sctp-failure from RTCError", err));
|
|
3115
|
+
} else {
|
|
3116
|
+
log12.info("unknown RTCError", {
|
|
3117
|
+
err
|
|
3112
3118
|
}, {
|
|
3113
3119
|
F: __dxlog_file13,
|
|
3114
|
-
L:
|
|
3120
|
+
L: 165,
|
|
3115
3121
|
S: this,
|
|
3116
3122
|
C: (f, a) => f(...a)
|
|
3117
3123
|
});
|
|
3118
|
-
this.
|
|
3119
|
-
return;
|
|
3124
|
+
this.errors.raise(new UnknownProtocolError2("unknown RTCError", err));
|
|
3120
3125
|
}
|
|
3121
|
-
|
|
3126
|
+
} else if ("code" in err) {
|
|
3127
|
+
log12.info("simple-peer error", err, {
|
|
3122
3128
|
F: __dxlog_file13,
|
|
3123
|
-
L:
|
|
3129
|
+
L: 170,
|
|
3124
3130
|
S: this,
|
|
3125
3131
|
C: (f, a) => f(...a)
|
|
3126
3132
|
});
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3133
|
+
switch (err.code) {
|
|
3134
|
+
case "ERR_WEBRTC_SUPPORT":
|
|
3135
|
+
this.errors.raise(new ProtocolError2("WebRTC not supported", err));
|
|
3136
|
+
break;
|
|
3137
|
+
case "ERR_SIGNALING":
|
|
3138
|
+
this.errors.raise(new ConnectivityError2("signaling failure", err));
|
|
3139
|
+
break;
|
|
3140
|
+
case "ERR_ICE_CONNECTION_FAILURE":
|
|
3141
|
+
case "ERR_DATA_CHANNEL":
|
|
3142
|
+
case "ERR_CONNECTION_FAILURE":
|
|
3143
|
+
this.errors.raise(new ConnectivityError2("unknown communication failure", err));
|
|
3144
|
+
break;
|
|
3145
|
+
// errors due to library issues or improper API usage
|
|
3146
|
+
case "ERR_CREATE_OFFER":
|
|
3147
|
+
case "ERR_CREATE_ANSWER":
|
|
3148
|
+
case "ERR_SET_LOCAL_DESCRIPTION":
|
|
3149
|
+
case "ERR_SET_REMOTE_DESCRIPTION":
|
|
3150
|
+
case "ERR_ADD_ICE_CANDIDATE":
|
|
3151
|
+
this.errors.raise(new UnknownProtocolError2("unknown simple-peer library failure", err));
|
|
3152
|
+
break;
|
|
3153
|
+
default:
|
|
3154
|
+
this.errors.raise(new Error("unknown simple-peer error"));
|
|
3155
|
+
break;
|
|
3156
|
+
}
|
|
3157
|
+
} else {
|
|
3158
|
+
log12.info("unknown peer connection error", err, {
|
|
3140
3159
|
F: __dxlog_file13,
|
|
3141
|
-
L:
|
|
3160
|
+
L: 196,
|
|
3142
3161
|
S: this,
|
|
3143
3162
|
C: (f, a) => f(...a)
|
|
3144
3163
|
});
|
|
3145
|
-
|
|
3146
|
-
}
|
|
3147
|
-
|
|
3148
|
-
if (
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3164
|
+
this.errors.raise(err);
|
|
3165
|
+
}
|
|
3166
|
+
try {
|
|
3167
|
+
if (typeof this._peer?._pc?.getStats === "function") {
|
|
3168
|
+
this._peer._pc.getStats().then((stats) => {
|
|
3169
|
+
log12.info("report after webrtc error", {
|
|
3170
|
+
config: this._params.webrtcConfig,
|
|
3171
|
+
stats: Object.fromEntries(stats.entries())
|
|
3172
|
+
}, {
|
|
3173
|
+
F: __dxlog_file13,
|
|
3174
|
+
L: 204,
|
|
3175
|
+
S: this,
|
|
3176
|
+
C: (f, a) => f(...a)
|
|
3177
|
+
});
|
|
3154
3178
|
});
|
|
3155
|
-
return;
|
|
3156
3179
|
}
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
data = Buffer.from(data);
|
|
3160
|
-
}
|
|
3161
|
-
this._stream.push(data);
|
|
3162
|
-
},
|
|
3163
|
-
onerror: (event) => {
|
|
3164
|
-
if (this.isOpen) {
|
|
3165
|
-
const err = event.error instanceof Error ? event.error : new Error(`Datachannel error: ${event.type}.`);
|
|
3166
|
-
this.errors.raise(err);
|
|
3167
|
-
}
|
|
3168
|
-
},
|
|
3169
|
-
onbufferedamountlow: () => {
|
|
3170
|
-
const cb = this._streamDataFlushedCallback;
|
|
3171
|
-
this._streamDataFlushedCallback = null;
|
|
3172
|
-
cb?.();
|
|
3173
|
-
}
|
|
3174
|
-
});
|
|
3175
|
-
}
|
|
3176
|
-
async _handleChannelWrite(chunk, callback) {
|
|
3177
|
-
if (!this._channel) {
|
|
3178
|
-
log12.warn("writing to a channel after a connection was closed", void 0, {
|
|
3179
|
-
F: __dxlog_file13,
|
|
3180
|
-
L: 145,
|
|
3181
|
-
S: this,
|
|
3182
|
-
C: (f, a) => f(...a)
|
|
3183
|
-
});
|
|
3184
|
-
return;
|
|
3185
|
-
}
|
|
3186
|
-
if (chunk.length > MAX_MESSAGE_SIZE) {
|
|
3187
|
-
const error = new Error(`Message too large: ${chunk.length} > ${MAX_MESSAGE_SIZE}.`);
|
|
3188
|
-
this.errors.raise(error);
|
|
3189
|
-
callback();
|
|
3190
|
-
return;
|
|
3191
|
-
}
|
|
3192
|
-
try {
|
|
3193
|
-
this._channel.send(chunk);
|
|
3194
|
-
} catch (err) {
|
|
3195
|
-
this.errors.raise(err);
|
|
3196
|
-
callback();
|
|
3197
|
-
return;
|
|
3198
|
-
}
|
|
3199
|
-
if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {
|
|
3200
|
-
if (this._streamDataFlushedCallback !== null) {
|
|
3201
|
-
log12.error("consumer trying to write before we are ready for more data", void 0, {
|
|
3180
|
+
} catch (err2) {
|
|
3181
|
+
log12.catch(err2, void 0, {
|
|
3202
3182
|
F: __dxlog_file13,
|
|
3203
|
-
L:
|
|
3183
|
+
L: 211,
|
|
3204
3184
|
S: this,
|
|
3205
3185
|
C: (f, a) => f(...a)
|
|
3206
3186
|
});
|
|
3207
3187
|
}
|
|
3208
|
-
this.
|
|
3209
|
-
}
|
|
3210
|
-
|
|
3211
|
-
|
|
3188
|
+
await this.close();
|
|
3189
|
+
});
|
|
3190
|
+
log12.trace("dxos.mesh.webrtc-transport.open", trace4.end({
|
|
3191
|
+
id: this._instanceId
|
|
3192
|
+
}), {
|
|
3193
|
+
F: __dxlog_file13,
|
|
3194
|
+
L: 217,
|
|
3195
|
+
S: this,
|
|
3196
|
+
C: (f, a) => f(...a)
|
|
3197
|
+
});
|
|
3212
3198
|
}
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
});
|
|
3199
|
+
async close() {
|
|
3200
|
+
log12("closing...", void 0, {
|
|
3201
|
+
F: __dxlog_file13,
|
|
3202
|
+
L: 222,
|
|
3203
|
+
S: this,
|
|
3204
|
+
C: (f, a) => f(...a)
|
|
3205
|
+
});
|
|
3206
|
+
if (this._closed) {
|
|
3207
|
+
return;
|
|
3223
3208
|
}
|
|
3209
|
+
this._disconnectStreams();
|
|
3210
|
+
this._peer.destroy();
|
|
3211
|
+
this._closed = true;
|
|
3212
|
+
this.closed.emit();
|
|
3213
|
+
log12("closed", void 0, {
|
|
3214
|
+
F: __dxlog_file13,
|
|
3215
|
+
L: 230,
|
|
3216
|
+
S: this,
|
|
3217
|
+
C: (f, a) => f(...a)
|
|
3218
|
+
});
|
|
3224
3219
|
}
|
|
3225
|
-
onSignal(signal) {
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
async getDetails() {
|
|
3229
|
-
return describeSelectedRemoteCandidate(this._connection.currentConnection);
|
|
3230
|
-
}
|
|
3231
|
-
async getStats() {
|
|
3232
|
-
return createRtcTransportStats(this._connection.currentConnection, this._options.topic);
|
|
3233
|
-
}
|
|
3234
|
-
};
|
|
3235
|
-
|
|
3236
|
-
// packages/core/mesh/network-manager/src/transport/webrtc/utils.ts
|
|
3237
|
-
var chooseInitiatorPeer = (peer1Key, peer2Key) => peer1Key < peer2Key ? peer1Key : peer2Key;
|
|
3238
|
-
var areSdpEqual = (sdp1, sdp2) => {
|
|
3239
|
-
const sdp1Lines = deduplicatedSdpLines(sdp1);
|
|
3240
|
-
const sdp2Lines = deduplicatedSdpLines(sdp2);
|
|
3241
|
-
if (sdp1Lines.length !== sdp2Lines.length) {
|
|
3242
|
-
return false;
|
|
3243
|
-
}
|
|
3244
|
-
return sdp1Lines.every((line, idx) => line === sdp2Lines[idx]);
|
|
3245
|
-
};
|
|
3246
|
-
var deduplicatedSdpLines = (sdp) => {
|
|
3247
|
-
const deduplicatedLines = [];
|
|
3248
|
-
const seenLines = [];
|
|
3249
|
-
for (const line of sdp.split("\r\n")) {
|
|
3250
|
-
if (line.startsWith("m")) {
|
|
3251
|
-
seenLines.length = 0;
|
|
3220
|
+
async onSignal(signal) {
|
|
3221
|
+
if (this._closed) {
|
|
3222
|
+
return;
|
|
3252
3223
|
}
|
|
3253
|
-
|
|
3254
|
-
|
|
3224
|
+
invariant11(signal.payload.data, "Signal message must contain signal data.");
|
|
3225
|
+
invariant11(this._peer, "Peer must be initialized before receiving signals.");
|
|
3226
|
+
this._peer.signal(signal.payload.data);
|
|
3227
|
+
}
|
|
3228
|
+
_disconnectStreams() {
|
|
3229
|
+
if (this._piped) {
|
|
3230
|
+
this._params.stream.unpipe?.(this._peer)?.unpipe?.(this._params.stream);
|
|
3255
3231
|
}
|
|
3256
|
-
seenLines.push(line);
|
|
3257
|
-
deduplicatedLines.push(line);
|
|
3258
3232
|
}
|
|
3259
|
-
return deduplicatedLines;
|
|
3260
3233
|
};
|
|
3234
|
+
_ts_decorate6([
|
|
3235
|
+
synchronized5
|
|
3236
|
+
], SimplePeerTransport.prototype, "open", null);
|
|
3237
|
+
_ts_decorate6([
|
|
3238
|
+
synchronized5
|
|
3239
|
+
], SimplePeerTransport.prototype, "close", null);
|
|
3240
|
+
_ts_decorate6([
|
|
3241
|
+
synchronized5
|
|
3242
|
+
], SimplePeerTransport.prototype, "onSignal", null);
|
|
3261
3243
|
|
|
3262
|
-
// packages/core/mesh/network-manager/src/transport/
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
}
|
|
3269
|
-
|
|
3270
|
-
var
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
this.
|
|
3274
|
-
this.
|
|
3275
|
-
this.
|
|
3276
|
-
this._dataChannels = /* @__PURE__ */ new Map();
|
|
3277
|
-
this._readyForCandidates = new Trigger3();
|
|
3278
|
-
this._offerProcessingMutex = new Mutex2();
|
|
3279
|
-
this._initiator = chooseInitiatorPeer(_options.ownPeerKey, _options.remotePeerKey) === _options.ownPeerKey;
|
|
3280
|
-
}
|
|
3281
|
-
get transportChannelCount() {
|
|
3282
|
-
return this._transportChannels.size;
|
|
3283
|
-
}
|
|
3284
|
-
get currentConnection() {
|
|
3285
|
-
return this._connection;
|
|
3286
|
-
}
|
|
3287
|
-
async createDataChannel(topic) {
|
|
3288
|
-
const connection = await this._openConnection();
|
|
3289
|
-
if (!this._transportChannels.has(topic)) {
|
|
3290
|
-
if (!this._transportChannels.size) {
|
|
3291
|
-
this._lockAndCloseConnection();
|
|
3292
|
-
}
|
|
3293
|
-
throw new Error("Transport closed while connection was being open");
|
|
3294
|
-
}
|
|
3295
|
-
if (this._initiator) {
|
|
3296
|
-
const channel = connection.createDataChannel(topic);
|
|
3297
|
-
this._dataChannels.set(topic, channel);
|
|
3298
|
-
return channel;
|
|
3299
|
-
} else {
|
|
3300
|
-
const existingChannel = this._dataChannels.get(topic);
|
|
3301
|
-
if (existingChannel) {
|
|
3302
|
-
return existingChannel;
|
|
3303
|
-
}
|
|
3304
|
-
log13("waiting for initiator-peer to open a data channel", void 0, {
|
|
3305
|
-
F: __dxlog_file14,
|
|
3306
|
-
L: 90,
|
|
3307
|
-
S: this,
|
|
3308
|
-
C: (f, a) => f(...a)
|
|
3309
|
-
});
|
|
3310
|
-
return new Promise((resolve, reject) => {
|
|
3311
|
-
this._channelCreatedCallbacks.set(topic, {
|
|
3312
|
-
resolve,
|
|
3313
|
-
reject
|
|
3314
|
-
});
|
|
3315
|
-
});
|
|
3316
|
-
}
|
|
3317
|
-
}
|
|
3318
|
-
createTransportChannel(options) {
|
|
3319
|
-
const channel = new RtcTransportChannel(this, options);
|
|
3320
|
-
this._transportChannels.set(options.topic, channel);
|
|
3321
|
-
channel.closed.on(() => {
|
|
3322
|
-
this._transportChannels.delete(options.topic);
|
|
3323
|
-
if (this._transportChannels.size === 0) {
|
|
3324
|
-
this._lockAndCloseConnection();
|
|
3325
|
-
}
|
|
3326
|
-
});
|
|
3327
|
-
return channel;
|
|
3244
|
+
// packages/core/mesh/network-manager/src/transport/simplepeer-transport-service.ts
|
|
3245
|
+
import { Duplex } from "@dxos/node-std/stream";
|
|
3246
|
+
import { Stream } from "@dxos/codec-protobuf";
|
|
3247
|
+
import { invariant as invariant12 } from "@dxos/invariant";
|
|
3248
|
+
import { PublicKey as PublicKey11 } from "@dxos/keys";
|
|
3249
|
+
import { log as log13 } from "@dxos/log";
|
|
3250
|
+
import { ConnectionState as ConnectionState3 } from "@dxos/protocols/proto/dxos/mesh/bridge";
|
|
3251
|
+
import { ComplexMap as ComplexMap8 } from "@dxos/util";
|
|
3252
|
+
var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/simplepeer-transport-service.ts";
|
|
3253
|
+
var SimplePeerTransportService = class {
|
|
3254
|
+
constructor(_webrtcConfig, _iceProvider) {
|
|
3255
|
+
this._webrtcConfig = _webrtcConfig;
|
|
3256
|
+
this._iceProvider = _iceProvider;
|
|
3257
|
+
this.transports = new ComplexMap8(PublicKey11.hash);
|
|
3328
3258
|
}
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
invariant12(this._initiator, void 0, {
|
|
3347
|
-
F: __dxlog_file14,
|
|
3348
|
-
L: 130,
|
|
3349
|
-
S: this,
|
|
3350
|
-
A: [
|
|
3351
|
-
"this._initiator",
|
|
3352
|
-
""
|
|
3353
|
-
]
|
|
3354
|
-
});
|
|
3355
|
-
if (connection !== this._connection) {
|
|
3356
|
-
this._onConnectionCallbackAfterClose("onnegotiationneeded", connection);
|
|
3357
|
-
return;
|
|
3358
|
-
}
|
|
3359
|
-
log13("onnegotiationneeded", void 0, {
|
|
3360
|
-
F: __dxlog_file14,
|
|
3361
|
-
L: 137,
|
|
3362
|
-
S: this,
|
|
3363
|
-
C: (f, a) => f(...a)
|
|
3364
|
-
});
|
|
3365
|
-
try {
|
|
3366
|
-
const offer = await connection.createOffer();
|
|
3367
|
-
await connection.setLocalDescription(offer);
|
|
3368
|
-
await this._sendDescription(connection, offer);
|
|
3369
|
-
} catch (err) {
|
|
3370
|
-
this._lockAndAbort(connection, err);
|
|
3371
|
-
}
|
|
3372
|
-
},
|
|
3373
|
-
// When ICE candidate identified (should be sent to remote peer) and when ICE gathering finalized.
|
|
3374
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidate_event
|
|
3375
|
-
onicecandidate: async (event) => {
|
|
3376
|
-
if (connection !== this._connection) {
|
|
3377
|
-
this._onConnectionCallbackAfterClose("onicecandidate", connection);
|
|
3378
|
-
return;
|
|
3379
|
-
}
|
|
3380
|
-
if (event.candidate) {
|
|
3381
|
-
log13("onicecandidate", {
|
|
3382
|
-
candidate: event.candidate.candidate
|
|
3383
|
-
}, {
|
|
3384
|
-
F: __dxlog_file14,
|
|
3385
|
-
L: 156,
|
|
3386
|
-
S: this,
|
|
3387
|
-
C: (f, a) => f(...a)
|
|
3388
|
-
});
|
|
3389
|
-
await this._sendIceCandidate(event.candidate);
|
|
3390
|
-
} else {
|
|
3391
|
-
log13("onicecandidate gathering complete", void 0, {
|
|
3392
|
-
F: __dxlog_file14,
|
|
3393
|
-
L: 159,
|
|
3394
|
-
S: this,
|
|
3395
|
-
C: (f, a) => f(...a)
|
|
3259
|
+
open(request) {
|
|
3260
|
+
const rpcStream = new Stream(({ ready, next, close }) => {
|
|
3261
|
+
const duplex = new Duplex({
|
|
3262
|
+
read: () => {
|
|
3263
|
+
const callbacks = [
|
|
3264
|
+
...transportState.writeCallbacks
|
|
3265
|
+
];
|
|
3266
|
+
transportState.writeCallbacks.length = 0;
|
|
3267
|
+
for (const cb of callbacks) {
|
|
3268
|
+
cb();
|
|
3269
|
+
}
|
|
3270
|
+
},
|
|
3271
|
+
write: function(chunk, _, callback) {
|
|
3272
|
+
next({
|
|
3273
|
+
data: {
|
|
3274
|
+
payload: chunk
|
|
3275
|
+
}
|
|
3396
3276
|
});
|
|
3277
|
+
callback();
|
|
3397
3278
|
}
|
|
3398
|
-
}
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
}
|
|
3417
|
-
log13("oniceconnectionstatechange", {
|
|
3418
|
-
state: connection.iceConnectionState
|
|
3419
|
-
}, {
|
|
3420
|
-
F: __dxlog_file14,
|
|
3421
|
-
L: 179,
|
|
3422
|
-
S: this,
|
|
3423
|
-
C: (f, a) => f(...a)
|
|
3424
|
-
});
|
|
3425
|
-
if (connection.iceConnectionState === "failed") {
|
|
3426
|
-
this._lockAndAbort(connection, createIceFailureError(iceCandidateErrors));
|
|
3279
|
+
});
|
|
3280
|
+
const transport = new SimplePeerTransport({
|
|
3281
|
+
initiator: request.initiator,
|
|
3282
|
+
stream: duplex,
|
|
3283
|
+
webrtcConfig: this._webrtcConfig,
|
|
3284
|
+
sendSignal: async (signal) => {
|
|
3285
|
+
next({
|
|
3286
|
+
signal: {
|
|
3287
|
+
payload: signal
|
|
3288
|
+
}
|
|
3289
|
+
});
|
|
3290
|
+
},
|
|
3291
|
+
iceProvider: this._iceProvider
|
|
3292
|
+
});
|
|
3293
|
+
void transport.open();
|
|
3294
|
+
next({
|
|
3295
|
+
connection: {
|
|
3296
|
+
state: ConnectionState3.CONNECTING
|
|
3427
3297
|
}
|
|
3428
|
-
}
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
if (connection !== this._connection) {
|
|
3434
|
-
if (connection.connectionState !== "closed" && connection.connectionState !== "failed") {
|
|
3435
|
-
this._onConnectionCallbackAfterClose("onconnectionstatechange", connection);
|
|
3298
|
+
});
|
|
3299
|
+
transport.connected.on(() => {
|
|
3300
|
+
next({
|
|
3301
|
+
connection: {
|
|
3302
|
+
state: ConnectionState3.CONNECTED
|
|
3436
3303
|
}
|
|
3437
|
-
return;
|
|
3438
|
-
}
|
|
3439
|
-
log13("onconnectionstatechange", {
|
|
3440
|
-
state: connection.connectionState
|
|
3441
|
-
}, {
|
|
3442
|
-
F: __dxlog_file14,
|
|
3443
|
-
L: 196,
|
|
3444
|
-
S: this,
|
|
3445
|
-
C: (f, a) => f(...a)
|
|
3446
|
-
});
|
|
3447
|
-
if (connection.connectionState === "failed") {
|
|
3448
|
-
this._lockAndAbort(connection, new Error("Connection failed."));
|
|
3449
|
-
}
|
|
3450
|
-
},
|
|
3451
|
-
onsignalingstatechange: () => {
|
|
3452
|
-
log13("onsignalingstatechange", {
|
|
3453
|
-
state: connection.signalingState
|
|
3454
|
-
}, {
|
|
3455
|
-
F: __dxlog_file14,
|
|
3456
|
-
L: 203,
|
|
3457
|
-
S: this,
|
|
3458
|
-
C: (f, a) => f(...a)
|
|
3459
3304
|
});
|
|
3460
|
-
}
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
S: this,
|
|
3468
|
-
A: [
|
|
3469
|
-
"!this._initiator",
|
|
3470
|
-
"'Initiator is expected to create data channels.'"
|
|
3471
|
-
]
|
|
3305
|
+
});
|
|
3306
|
+
transport.errors.handle((err) => {
|
|
3307
|
+
next({
|
|
3308
|
+
connection: {
|
|
3309
|
+
state: ConnectionState3.CLOSED,
|
|
3310
|
+
error: err.toString()
|
|
3311
|
+
}
|
|
3472
3312
|
});
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
F: __dxlog_file14,
|
|
3481
|
-
L: 216,
|
|
3482
|
-
S: this,
|
|
3483
|
-
C: (f, a) => f(...a)
|
|
3313
|
+
close(err);
|
|
3314
|
+
});
|
|
3315
|
+
transport.closed.on(() => {
|
|
3316
|
+
next({
|
|
3317
|
+
connection: {
|
|
3318
|
+
state: ConnectionState3.CLOSED
|
|
3319
|
+
}
|
|
3484
3320
|
});
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
await this._factory.initConnection(connection, {
|
|
3496
|
-
initiator: this._initiator
|
|
3321
|
+
close();
|
|
3322
|
+
});
|
|
3323
|
+
const transportState = {
|
|
3324
|
+
transport,
|
|
3325
|
+
stream: duplex,
|
|
3326
|
+
writeCallbacks: [],
|
|
3327
|
+
state: "OPEN"
|
|
3328
|
+
};
|
|
3329
|
+
ready();
|
|
3330
|
+
this.transports.set(request.proxyId, transportState);
|
|
3497
3331
|
});
|
|
3498
|
-
return
|
|
3332
|
+
return rpcStream;
|
|
3499
3333
|
}
|
|
3500
|
-
|
|
3501
|
-
this.
|
|
3334
|
+
async sendSignal({ proxyId, signal }) {
|
|
3335
|
+
invariant12(this.transports.has(proxyId), void 0, {
|
|
3336
|
+
F: __dxlog_file14,
|
|
3337
|
+
L: 124,
|
|
3338
|
+
S: this,
|
|
3339
|
+
A: [
|
|
3340
|
+
"this.transports.has(proxyId)",
|
|
3341
|
+
""
|
|
3342
|
+
]
|
|
3343
|
+
});
|
|
3344
|
+
await this.transports.get(proxyId).transport.onSignal(signal);
|
|
3502
3345
|
}
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
log13.error("attempted to abort an inactive connection", {
|
|
3506
|
-
error
|
|
3507
|
-
}, {
|
|
3508
|
-
F: __dxlog_file14,
|
|
3509
|
-
L: 241,
|
|
3510
|
-
S: this,
|
|
3511
|
-
C: (f, a) => f(...a)
|
|
3512
|
-
});
|
|
3513
|
-
this._safeCloseConnection(connection);
|
|
3514
|
-
return;
|
|
3515
|
-
}
|
|
3516
|
-
for (const [topic, pendingCallback] of this._channelCreatedCallbacks.entries()) {
|
|
3517
|
-
pendingCallback.reject(error);
|
|
3518
|
-
this._transportChannels.delete(topic);
|
|
3519
|
-
}
|
|
3520
|
-
this._channelCreatedCallbacks.clear();
|
|
3521
|
-
for (const channel of this._transportChannels.values()) {
|
|
3522
|
-
channel.onConnectionError(error);
|
|
3523
|
-
}
|
|
3524
|
-
this._transportChannels.clear();
|
|
3525
|
-
this._safeCloseConnection();
|
|
3526
|
-
log13("connection aborted", {
|
|
3527
|
-
reason: error.message
|
|
3528
|
-
}, {
|
|
3346
|
+
async getDetails({ proxyId }) {
|
|
3347
|
+
invariant12(this.transports.has(proxyId), void 0, {
|
|
3529
3348
|
F: __dxlog_file14,
|
|
3530
|
-
L:
|
|
3349
|
+
L: 129,
|
|
3531
3350
|
S: this,
|
|
3532
|
-
|
|
3351
|
+
A: [
|
|
3352
|
+
"this.transports.has(proxyId)",
|
|
3353
|
+
""
|
|
3354
|
+
]
|
|
3533
3355
|
});
|
|
3356
|
+
return {
|
|
3357
|
+
details: await this.transports.get(proxyId).transport.getDetails()
|
|
3358
|
+
};
|
|
3534
3359
|
}
|
|
3535
|
-
|
|
3536
|
-
invariant12(this.
|
|
3360
|
+
async getStats({ proxyId }) {
|
|
3361
|
+
invariant12(this.transports.has(proxyId), void 0, {
|
|
3537
3362
|
F: __dxlog_file14,
|
|
3538
|
-
L:
|
|
3363
|
+
L: 134,
|
|
3539
3364
|
S: this,
|
|
3540
3365
|
A: [
|
|
3541
|
-
"this.
|
|
3366
|
+
"this.transports.has(proxyId)",
|
|
3542
3367
|
""
|
|
3543
3368
|
]
|
|
3544
3369
|
});
|
|
3545
|
-
|
|
3546
|
-
this.
|
|
3547
|
-
|
|
3548
|
-
F: __dxlog_file14,
|
|
3549
|
-
L: 263,
|
|
3550
|
-
S: this,
|
|
3551
|
-
C: (f, a) => f(...a)
|
|
3552
|
-
});
|
|
3553
|
-
}
|
|
3370
|
+
return {
|
|
3371
|
+
stats: await this.transports.get(proxyId).transport.getStats()
|
|
3372
|
+
};
|
|
3554
3373
|
}
|
|
3555
|
-
async
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
log13.warn("a signal ignored because the connection was closed", {
|
|
3559
|
-
type: signal.payload.data.type
|
|
3560
|
-
}, {
|
|
3374
|
+
async sendData({ proxyId, payload }) {
|
|
3375
|
+
if (this.transports.get(proxyId)?.state !== "OPEN") {
|
|
3376
|
+
log13.debug("transport is closed", void 0, {
|
|
3561
3377
|
F: __dxlog_file14,
|
|
3562
|
-
L:
|
|
3378
|
+
L: 140,
|
|
3563
3379
|
S: this,
|
|
3564
3380
|
C: (f, a) => f(...a)
|
|
3565
3381
|
});
|
|
3566
|
-
return;
|
|
3567
|
-
}
|
|
3568
|
-
const data = signal.payload.data;
|
|
3569
|
-
switch (data.type) {
|
|
3570
|
-
case "offer": {
|
|
3571
|
-
await this._offerProcessingMutex.executeSynchronized(async () => {
|
|
3572
|
-
if (isRemoteDescriptionSet(connection, data)) {
|
|
3573
|
-
return;
|
|
3574
|
-
}
|
|
3575
|
-
if (connection.connectionState !== "new") {
|
|
3576
|
-
this._abortConnection(connection, new Error(`Received an offer in ${connection.connectionState}.`));
|
|
3577
|
-
return;
|
|
3578
|
-
}
|
|
3579
|
-
try {
|
|
3580
|
-
await connection.setRemoteDescription({
|
|
3581
|
-
type: data.type,
|
|
3582
|
-
sdp: data.sdp
|
|
3583
|
-
});
|
|
3584
|
-
const answer = await connection.createAnswer();
|
|
3585
|
-
await connection.setLocalDescription(answer);
|
|
3586
|
-
await this._sendDescription(connection, answer);
|
|
3587
|
-
this._onSessionNegotiated(connection);
|
|
3588
|
-
} catch (err) {
|
|
3589
|
-
this._abortConnection(connection, new Error("Error handling a remote offer.", {
|
|
3590
|
-
cause: err
|
|
3591
|
-
}));
|
|
3592
|
-
}
|
|
3593
|
-
});
|
|
3594
|
-
break;
|
|
3595
|
-
}
|
|
3596
|
-
case "answer":
|
|
3597
|
-
await this._offerProcessingMutex.executeSynchronized(async () => {
|
|
3598
|
-
try {
|
|
3599
|
-
if (isRemoteDescriptionSet(connection, data)) {
|
|
3600
|
-
return;
|
|
3601
|
-
}
|
|
3602
|
-
if (connection.signalingState !== "have-local-offer") {
|
|
3603
|
-
this._abortConnection(connection, new Error(`Unexpected answer from remote peer, signalingState was ${connection.signalingState}.`));
|
|
3604
|
-
return;
|
|
3605
|
-
}
|
|
3606
|
-
await connection.setRemoteDescription({
|
|
3607
|
-
type: data.type,
|
|
3608
|
-
sdp: data.sdp
|
|
3609
|
-
});
|
|
3610
|
-
this._onSessionNegotiated(connection);
|
|
3611
|
-
} catch (err) {
|
|
3612
|
-
this._abortConnection(connection, new Error("Error handling a remote answer.", {
|
|
3613
|
-
cause: err
|
|
3614
|
-
}));
|
|
3615
|
-
}
|
|
3616
|
-
});
|
|
3617
|
-
break;
|
|
3618
|
-
case "candidate":
|
|
3619
|
-
void this._processIceCandidate(connection, data.candidate);
|
|
3620
|
-
break;
|
|
3621
|
-
default:
|
|
3622
|
-
this._abortConnection(connection, new Error(`Unknown signal type ${data.type}.`));
|
|
3623
|
-
break;
|
|
3624
3382
|
}
|
|
3625
|
-
|
|
3383
|
+
invariant12(this.transports.has(proxyId), void 0, {
|
|
3626
3384
|
F: __dxlog_file14,
|
|
3627
|
-
L:
|
|
3385
|
+
L: 142,
|
|
3628
3386
|
S: this,
|
|
3629
|
-
|
|
3387
|
+
A: [
|
|
3388
|
+
"this.transports.has(proxyId)",
|
|
3389
|
+
""
|
|
3390
|
+
]
|
|
3630
3391
|
});
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
await
|
|
3635
|
-
|
|
3636
|
-
log13("adding ice candidate", {
|
|
3637
|
-
candidate
|
|
3638
|
-
}, {
|
|
3639
|
-
F: __dxlog_file14,
|
|
3640
|
-
L: 338,
|
|
3641
|
-
S: this,
|
|
3642
|
-
C: (f, a) => f(...a)
|
|
3643
|
-
});
|
|
3644
|
-
await connection.addIceCandidate(candidate);
|
|
3645
|
-
}
|
|
3646
|
-
} catch (err) {
|
|
3647
|
-
log13.catch(err, void 0, {
|
|
3648
|
-
F: __dxlog_file14,
|
|
3649
|
-
L: 342,
|
|
3650
|
-
S: this,
|
|
3651
|
-
C: (f, a) => f(...a)
|
|
3392
|
+
const state = this.transports.get(proxyId);
|
|
3393
|
+
const bufferHasSpace = state.stream.push(payload);
|
|
3394
|
+
if (!bufferHasSpace) {
|
|
3395
|
+
await new Promise((resolve) => {
|
|
3396
|
+
state.writeCallbacks.push(resolve);
|
|
3652
3397
|
});
|
|
3653
3398
|
}
|
|
3654
3399
|
}
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
S: this,
|
|
3661
|
-
C: (f, a) => f(...a)
|
|
3662
|
-
});
|
|
3663
|
-
this._readyForCandidates.wake();
|
|
3664
|
-
} else {
|
|
3665
|
-
log13.warn("session was negotiated after connection became inactive", void 0, {
|
|
3666
|
-
F: __dxlog_file14,
|
|
3667
|
-
L: 351,
|
|
3668
|
-
S: this,
|
|
3669
|
-
C: (f, a) => f(...a)
|
|
3670
|
-
});
|
|
3400
|
+
async close({ proxyId }) {
|
|
3401
|
+
await this.transports.get(proxyId)?.transport.close();
|
|
3402
|
+
await this.transports.get(proxyId)?.stream.end();
|
|
3403
|
+
if (this.transports.get(proxyId)) {
|
|
3404
|
+
this.transports.get(proxyId).state = "CLOSED";
|
|
3671
3405
|
}
|
|
3672
|
-
|
|
3673
|
-
_onConnectionCallbackAfterClose(callback, connection) {
|
|
3674
|
-
log13.warn("callback invoked after a connection was destroyed, this is probably a bug", {
|
|
3675
|
-
callback,
|
|
3676
|
-
state: connection.connectionState
|
|
3677
|
-
}, {
|
|
3406
|
+
log13("Closed.", void 0, {
|
|
3678
3407
|
F: __dxlog_file14,
|
|
3679
|
-
L:
|
|
3408
|
+
L: 158,
|
|
3680
3409
|
S: this,
|
|
3681
3410
|
C: (f, a) => f(...a)
|
|
3682
3411
|
});
|
|
3683
|
-
this._safeCloseConnection(connection);
|
|
3684
3412
|
}
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3413
|
+
};
|
|
3414
|
+
|
|
3415
|
+
// packages/core/mesh/network-manager/src/transport/simplepeer-transport-proxy.ts
|
|
3416
|
+
import { Writable } from "@dxos/node-std/stream";
|
|
3417
|
+
import { Event as Event9, scheduleTask as scheduleTask4 } from "@dxos/async";
|
|
3418
|
+
import { Context as Context6 } from "@dxos/context";
|
|
3419
|
+
import { ErrorStream as ErrorStream5 } from "@dxos/debug";
|
|
3420
|
+
import { invariant as invariant13 } from "@dxos/invariant";
|
|
3421
|
+
import { PublicKey as PublicKey12 } from "@dxos/keys";
|
|
3422
|
+
import { log as log14 } from "@dxos/log";
|
|
3423
|
+
import { ConnectionResetError as ConnectionResetError3, TimeoutError as TimeoutError3, ProtocolError as ProtocolError3, ConnectivityError as ConnectivityError3, UnknownProtocolError as UnknownProtocolError3 } from "@dxos/protocols";
|
|
3424
|
+
import { ConnectionState as ConnectionState4 } from "@dxos/protocols/proto/dxos/mesh/bridge";
|
|
3425
|
+
import { arrayToBuffer } from "@dxos/util";
|
|
3426
|
+
var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/simplepeer-transport-proxy.ts";
|
|
3427
|
+
var RPC_TIMEOUT = 1e4;
|
|
3428
|
+
var RESP_MIN_THRESHOLD = 500;
|
|
3429
|
+
var TIMEOUT_THRESHOLD = 10;
|
|
3430
|
+
var SimplePeerTransportProxy = class {
|
|
3431
|
+
constructor(_options) {
|
|
3432
|
+
this._options = _options;
|
|
3433
|
+
this._proxyId = PublicKey12.random();
|
|
3434
|
+
this._ctx = new Context6(void 0, {
|
|
3435
|
+
F: __dxlog_file15,
|
|
3436
|
+
L: 37
|
|
3437
|
+
});
|
|
3438
|
+
this._timeoutCount = 0;
|
|
3439
|
+
this.closed = new Event9();
|
|
3440
|
+
this.connected = new Event9();
|
|
3441
|
+
this.errors = new ErrorStream5();
|
|
3442
|
+
this._closed = false;
|
|
3712
3443
|
}
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
...this._options.webrtcConfig
|
|
3716
|
-
};
|
|
3717
|
-
try {
|
|
3718
|
-
const providedIceServers = await this._options.iceProvider?.getIceServers() ?? [];
|
|
3719
|
-
if (providedIceServers.length > 0) {
|
|
3720
|
-
config.iceServers = [
|
|
3721
|
-
...config.iceServers ?? [],
|
|
3722
|
-
...providedIceServers
|
|
3723
|
-
];
|
|
3724
|
-
}
|
|
3725
|
-
} catch (error) {
|
|
3726
|
-
log13.catch(error, void 0, {
|
|
3727
|
-
F: __dxlog_file14,
|
|
3728
|
-
L: 390,
|
|
3729
|
-
S: this,
|
|
3730
|
-
C: (f, a) => f(...a)
|
|
3731
|
-
});
|
|
3732
|
-
}
|
|
3733
|
-
return config;
|
|
3444
|
+
get isOpen() {
|
|
3445
|
+
return !this._closed;
|
|
3734
3446
|
}
|
|
3735
|
-
async
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3447
|
+
async open() {
|
|
3448
|
+
this._serviceStream = this._options.bridgeService.open({
|
|
3449
|
+
proxyId: this._proxyId,
|
|
3450
|
+
initiator: this._options.initiator
|
|
3451
|
+
}, {
|
|
3452
|
+
timeout: RPC_TIMEOUT
|
|
3453
|
+
});
|
|
3454
|
+
this._serviceStream.waitUntilReady().then(() => {
|
|
3455
|
+
this._serviceStream.subscribe(async (event) => {
|
|
3456
|
+
log14("SimplePeerTransportProxy: event", event, {
|
|
3457
|
+
F: __dxlog_file15,
|
|
3458
|
+
L: 66,
|
|
3459
|
+
S: this,
|
|
3460
|
+
C: (f, a) => f(...a)
|
|
3461
|
+
});
|
|
3462
|
+
if (event.connection) {
|
|
3463
|
+
await this._handleConnection(event.connection);
|
|
3464
|
+
} else if (event.data) {
|
|
3465
|
+
this._handleData(event.data);
|
|
3466
|
+
} else if (event.signal) {
|
|
3467
|
+
await this._handleSignal(event.signal);
|
|
3748
3468
|
}
|
|
3749
3469
|
});
|
|
3750
|
-
|
|
3751
|
-
log13.warn("signaling error", {
|
|
3752
|
-
err
|
|
3753
|
-
}, {
|
|
3754
|
-
F: __dxlog_file14,
|
|
3755
|
-
L: 411,
|
|
3756
|
-
S: this,
|
|
3757
|
-
C: (f, a) => f(...a)
|
|
3758
|
-
});
|
|
3759
|
-
}
|
|
3760
|
-
}
|
|
3761
|
-
async _sendDescription(connection, description) {
|
|
3762
|
-
if (connection !== this._connection) {
|
|
3763
|
-
return;
|
|
3764
|
-
}
|
|
3765
|
-
const data = {
|
|
3766
|
-
type: description.type,
|
|
3767
|
-
sdp: description.sdp
|
|
3768
|
-
};
|
|
3769
|
-
await this._options.sendSignal({
|
|
3770
|
-
payload: {
|
|
3771
|
-
data
|
|
3772
|
-
}
|
|
3773
|
-
});
|
|
3774
|
-
}
|
|
3775
|
-
get _connectionInfo() {
|
|
3776
|
-
const connectionInfo = this._connection && {
|
|
3777
|
-
connectionState: this._connection.connectionState,
|
|
3778
|
-
iceConnectionState: this._connection.iceConnectionState,
|
|
3779
|
-
iceGatheringState: this._connection.iceGatheringState,
|
|
3780
|
-
signalingState: this._connection.signalingState,
|
|
3781
|
-
remoteDescription: this._connection.remoteDescription,
|
|
3782
|
-
localDescription: this._connection.localDescription
|
|
3783
|
-
};
|
|
3784
|
-
return {
|
|
3785
|
-
...connectionInfo,
|
|
3786
|
-
ts: Date.now(),
|
|
3787
|
-
remotePeerKey: this._options.remotePeerKey,
|
|
3788
|
-
channels: [
|
|
3789
|
-
...this._transportChannels.keys()
|
|
3790
|
-
].map((topic) => topic),
|
|
3791
|
-
config: this._connection?.getConfiguration()
|
|
3792
|
-
};
|
|
3793
|
-
}
|
|
3794
|
-
get _loggerContext() {
|
|
3795
|
-
return {
|
|
3796
|
-
ownPeerKey: this._options.ownPeerKey,
|
|
3797
|
-
remotePeerKey: this._options.remotePeerKey,
|
|
3798
|
-
initiator: this._initiator,
|
|
3799
|
-
channels: this._transportChannels.size
|
|
3800
|
-
};
|
|
3801
|
-
}
|
|
3802
|
-
};
|
|
3803
|
-
_ts_decorate6([
|
|
3804
|
-
synchronized5
|
|
3805
|
-
], RtcPeerConnection.prototype, "_openConnection", null);
|
|
3806
|
-
_ts_decorate6([
|
|
3807
|
-
synchronized5
|
|
3808
|
-
], RtcPeerConnection.prototype, "_lockAndAbort", null);
|
|
3809
|
-
_ts_decorate6([
|
|
3810
|
-
synchronized5
|
|
3811
|
-
], RtcPeerConnection.prototype, "_lockAndCloseConnection", null);
|
|
3812
|
-
_ts_decorate6([
|
|
3813
|
-
synchronized5
|
|
3814
|
-
], RtcPeerConnection.prototype, "onSignal", null);
|
|
3815
|
-
_ts_decorate6([
|
|
3816
|
-
trace4.info()
|
|
3817
|
-
], RtcPeerConnection.prototype, "_connectionInfo", null);
|
|
3818
|
-
_ts_decorate6([
|
|
3819
|
-
logInfo4
|
|
3820
|
-
], RtcPeerConnection.prototype, "_loggerContext", null);
|
|
3821
|
-
RtcPeerConnection = _ts_decorate6([
|
|
3822
|
-
trace4.resource()
|
|
3823
|
-
], RtcPeerConnection);
|
|
3824
|
-
var isRemoteDescriptionSet = (connection, data) => {
|
|
3825
|
-
if (!connection.remoteDescription?.type || connection.remoteDescription?.type !== data.type) {
|
|
3826
|
-
return false;
|
|
3827
|
-
}
|
|
3828
|
-
return areSdpEqual(connection.remoteDescription.sdp, data.sdp);
|
|
3829
|
-
};
|
|
3830
|
-
var createIceFailureError = (details) => {
|
|
3831
|
-
const candidateErrors = details.map(({ url, errorCode, errorText }) => `${errorCode} ${url}: ${errorText}`);
|
|
3832
|
-
return new ConnectivityError3(`ICE failed:
|
|
3833
|
-
${candidateErrors.join("\n")}`);
|
|
3834
|
-
};
|
|
3835
|
-
|
|
3836
|
-
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-factory.ts
|
|
3837
|
-
var createRtcTransportFactory = (webrtcConfig, iceProvider) => {
|
|
3838
|
-
const connectionFactory = getRtcConnectionFactory();
|
|
3839
|
-
return {
|
|
3840
|
-
createTransport: (options) => {
|
|
3841
|
-
const connection = new RtcPeerConnection(connectionFactory, {
|
|
3842
|
-
ownPeerKey: options.ownPeerKey,
|
|
3843
|
-
remotePeerKey: options.remotePeerKey,
|
|
3844
|
-
sendSignal: options.sendSignal,
|
|
3845
|
-
webrtcConfig,
|
|
3846
|
-
iceProvider
|
|
3847
|
-
});
|
|
3848
|
-
return connection.createTransportChannel(options);
|
|
3849
|
-
}
|
|
3850
|
-
};
|
|
3851
|
-
};
|
|
3852
|
-
|
|
3853
|
-
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-proxy.ts
|
|
3854
|
-
import { Writable } from "@dxos/node-std/stream";
|
|
3855
|
-
import { Event as Event8, scheduleTask as scheduleTask4 } from "@dxos/async";
|
|
3856
|
-
import { Resource as Resource2 } from "@dxos/context";
|
|
3857
|
-
import { ErrorStream as ErrorStream5 } from "@dxos/debug";
|
|
3858
|
-
import { invariant as invariant13 } from "@dxos/invariant";
|
|
3859
|
-
import { PublicKey as PublicKey10 } from "@dxos/keys";
|
|
3860
|
-
import { log as log14 } from "@dxos/log";
|
|
3861
|
-
import { ConnectionResetError as ConnectionResetError2, ConnectivityError as ConnectivityError4, TimeoutError as TimeoutError3 } from "@dxos/protocols";
|
|
3862
|
-
import { ConnectionState as ConnectionState3 } from "@dxos/protocols/proto/dxos/mesh/bridge";
|
|
3863
|
-
import { arrayToBuffer } from "@dxos/util";
|
|
3864
|
-
var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-proxy.ts";
|
|
3865
|
-
var RPC_TIMEOUT = 1e4;
|
|
3866
|
-
var CLOSE_RPC_TIMEOUT = 3e3;
|
|
3867
|
-
var RESP_MIN_THRESHOLD = 500;
|
|
3868
|
-
var RtcTransportProxy = class extends Resource2 {
|
|
3869
|
-
constructor(_options) {
|
|
3870
|
-
super();
|
|
3871
|
-
this._options = _options;
|
|
3872
|
-
this._proxyId = PublicKey10.random();
|
|
3873
|
-
this.closed = new Event8();
|
|
3874
|
-
this.connected = new Event8();
|
|
3875
|
-
this.errors = new ErrorStream5();
|
|
3876
|
-
}
|
|
3877
|
-
async _open() {
|
|
3878
|
-
let stream;
|
|
3879
|
-
try {
|
|
3880
|
-
stream = this._options.bridgeService.open({
|
|
3881
|
-
proxyId: this._proxyId,
|
|
3882
|
-
remotePeerKey: this._options.remotePeerKey,
|
|
3883
|
-
ownPeerKey: this._options.ownPeerKey,
|
|
3884
|
-
topic: this._options.topic,
|
|
3885
|
-
initiator: this._options.initiator ?? false
|
|
3886
|
-
}, {
|
|
3887
|
-
timeout: RPC_TIMEOUT
|
|
3888
|
-
});
|
|
3889
|
-
} catch (error) {
|
|
3890
|
-
this.errors.raise(error);
|
|
3891
|
-
return;
|
|
3892
|
-
}
|
|
3893
|
-
this._serviceStream = stream;
|
|
3894
|
-
stream.waitUntilReady().then(() => {
|
|
3895
|
-
stream.subscribe(async (event) => {
|
|
3896
|
-
log14("rtc transport proxy event", event, {
|
|
3897
|
-
F: __dxlog_file15,
|
|
3898
|
-
L: 66,
|
|
3899
|
-
S: this,
|
|
3900
|
-
C: (f, a) => f(...a)
|
|
3901
|
-
});
|
|
3902
|
-
if (event.connection) {
|
|
3903
|
-
await this._handleConnection(event.connection);
|
|
3904
|
-
} else if (event.data) {
|
|
3905
|
-
this._handleData(event.data);
|
|
3906
|
-
} else if (event.signal) {
|
|
3907
|
-
await this._handleSignal(event.signal);
|
|
3908
|
-
}
|
|
3909
|
-
}, (err) => {
|
|
3910
|
-
log14("rtc bridge stream closed", {
|
|
3911
|
-
err
|
|
3912
|
-
}, {
|
|
3913
|
-
F: __dxlog_file15,
|
|
3914
|
-
L: 76,
|
|
3915
|
-
S: this,
|
|
3916
|
-
C: (f, a) => f(...a)
|
|
3917
|
-
});
|
|
3918
|
-
if (err) {
|
|
3919
|
-
this._raiseIfOpen(err);
|
|
3920
|
-
} else {
|
|
3921
|
-
void this.close();
|
|
3922
|
-
}
|
|
3923
|
-
});
|
|
3924
|
-
const connectorStream = new Writable({
|
|
3470
|
+
const proxyStream = new Writable({
|
|
3925
3471
|
write: (chunk, _, callback) => {
|
|
3926
|
-
const
|
|
3472
|
+
const then = performance.now();
|
|
3927
3473
|
this._options.bridgeService.sendData({
|
|
3928
3474
|
proxyId: this._proxyId,
|
|
3929
3475
|
payload: chunk
|
|
3930
3476
|
}, {
|
|
3931
3477
|
timeout: RPC_TIMEOUT
|
|
3932
3478
|
}).then(() => {
|
|
3933
|
-
if (
|
|
3479
|
+
if (performance.now() - then > RESP_MIN_THRESHOLD) {
|
|
3934
3480
|
log14("slow response, delaying callback", void 0, {
|
|
3935
3481
|
F: __dxlog_file15,
|
|
3936
|
-
L:
|
|
3482
|
+
L: 90,
|
|
3937
3483
|
S: this,
|
|
3938
3484
|
C: (f, a) => f(...a)
|
|
3939
3485
|
});
|
|
@@ -3941,41 +3487,60 @@ var RtcTransportProxy = class extends Resource2 {
|
|
|
3941
3487
|
} else {
|
|
3942
3488
|
callback();
|
|
3943
3489
|
}
|
|
3490
|
+
this._timeoutCount = 0;
|
|
3944
3491
|
}, (err) => {
|
|
3945
|
-
|
|
3946
|
-
|
|
3492
|
+
if (err instanceof TimeoutError3 || err.constructor.name === "TimeoutError") {
|
|
3493
|
+
if (this._timeoutCount++ > TIMEOUT_THRESHOLD) {
|
|
3494
|
+
throw new TimeoutError3(`too many timeouts (${this._timeoutCount} > ${TIMEOUT_THRESHOLD}`);
|
|
3495
|
+
} else {
|
|
3496
|
+
log14("timeout error, but still invoking callback", void 0, {
|
|
3497
|
+
F: __dxlog_file15,
|
|
3498
|
+
L: 102,
|
|
3499
|
+
S: this,
|
|
3500
|
+
C: (f, a) => f(...a)
|
|
3501
|
+
});
|
|
3502
|
+
callback();
|
|
3503
|
+
}
|
|
3504
|
+
} else {
|
|
3505
|
+
log14.catch(err, void 0, {
|
|
3506
|
+
F: __dxlog_file15,
|
|
3507
|
+
L: 106,
|
|
3508
|
+
S: this,
|
|
3509
|
+
C: (f, a) => f(...a)
|
|
3510
|
+
});
|
|
3511
|
+
}
|
|
3947
3512
|
});
|
|
3948
3513
|
}
|
|
3949
3514
|
});
|
|
3950
|
-
|
|
3951
|
-
|
|
3515
|
+
proxyStream.on("error", (err) => {
|
|
3516
|
+
log14("proxystream error", {
|
|
3517
|
+
err
|
|
3518
|
+
}, {
|
|
3519
|
+
F: __dxlog_file15,
|
|
3520
|
+
L: 114,
|
|
3521
|
+
S: this,
|
|
3522
|
+
C: (f, a) => f(...a)
|
|
3523
|
+
});
|
|
3952
3524
|
});
|
|
3953
|
-
this._options.stream.pipe(
|
|
3954
|
-
}, (error) => {
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
});
|
|
3525
|
+
this._options.stream.pipe(proxyStream);
|
|
3526
|
+
}, (error) => log14.catch(error, void 0, {
|
|
3527
|
+
F: __dxlog_file15,
|
|
3528
|
+
L: 119,
|
|
3529
|
+
S: this,
|
|
3530
|
+
C: (f, a) => f(...a)
|
|
3531
|
+
}));
|
|
3961
3532
|
}
|
|
3962
|
-
async
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
} catch (err) {
|
|
3967
|
-
log14.catch(err, void 0, {
|
|
3968
|
-
F: __dxlog_file15,
|
|
3969
|
-
L: 128,
|
|
3970
|
-
S: this,
|
|
3971
|
-
C: (f, a) => f(...a)
|
|
3972
|
-
});
|
|
3533
|
+
async close() {
|
|
3534
|
+
await this._ctx.dispose();
|
|
3535
|
+
if (this._closed) {
|
|
3536
|
+
return;
|
|
3973
3537
|
}
|
|
3538
|
+
await this._serviceStream.close();
|
|
3974
3539
|
try {
|
|
3975
3540
|
await this._options.bridgeService.close({
|
|
3976
3541
|
proxyId: this._proxyId
|
|
3977
3542
|
}, {
|
|
3978
|
-
timeout:
|
|
3543
|
+
timeout: RPC_TIMEOUT
|
|
3979
3544
|
});
|
|
3980
3545
|
} catch (err) {
|
|
3981
3546
|
log14.catch(err, void 0, {
|
|
@@ -3986,6 +3551,7 @@ var RtcTransportProxy = class extends Resource2 {
|
|
|
3986
3551
|
});
|
|
3987
3552
|
}
|
|
3988
3553
|
this.closed.emit();
|
|
3554
|
+
this._closed = true;
|
|
3989
3555
|
}
|
|
3990
3556
|
async onSignal(signal) {
|
|
3991
3557
|
this._options.bridgeService.sendSignal({
|
|
@@ -3993,94 +3559,54 @@ var RtcTransportProxy = class extends Resource2 {
|
|
|
3993
3559
|
signal
|
|
3994
3560
|
}, {
|
|
3995
3561
|
timeout: RPC_TIMEOUT
|
|
3996
|
-
}).catch((err) => this.
|
|
3562
|
+
}).catch((err) => this.errors.raise(decodeError(err)));
|
|
3997
3563
|
}
|
|
3998
3564
|
async _handleConnection(connectionEvent) {
|
|
3999
3565
|
if (connectionEvent.error) {
|
|
4000
3566
|
this.errors.raise(decodeError(connectionEvent.error));
|
|
4001
|
-
return;
|
|
4002
3567
|
}
|
|
4003
3568
|
switch (connectionEvent.state) {
|
|
4004
|
-
case
|
|
3569
|
+
case ConnectionState4.CONNECTED: {
|
|
4005
3570
|
this.connected.emit();
|
|
4006
3571
|
break;
|
|
4007
3572
|
}
|
|
4008
|
-
case
|
|
3573
|
+
case ConnectionState4.CLOSED: {
|
|
4009
3574
|
await this.close();
|
|
4010
3575
|
break;
|
|
4011
3576
|
}
|
|
4012
3577
|
}
|
|
4013
3578
|
}
|
|
4014
3579
|
_handleData(dataEvent) {
|
|
4015
|
-
|
|
4016
|
-
this._options.stream.write(arrayToBuffer(dataEvent.payload));
|
|
4017
|
-
} catch (error) {
|
|
4018
|
-
this._raiseIfOpen(error);
|
|
4019
|
-
}
|
|
3580
|
+
this._options.stream.write(arrayToBuffer(dataEvent.payload));
|
|
4020
3581
|
}
|
|
4021
3582
|
async _handleSignal(signalEvent) {
|
|
4022
|
-
|
|
4023
|
-
await this._options.sendSignal(signalEvent.payload);
|
|
4024
|
-
} catch (error) {
|
|
4025
|
-
const type = signalEvent.payload.payload.data?.type;
|
|
4026
|
-
if (type === "offer" || type === "answer") {
|
|
4027
|
-
this._raiseIfOpen(new ConnectivityError4(`Session establishment failed: ${type} couldn't be sent.`));
|
|
4028
|
-
}
|
|
4029
|
-
}
|
|
3583
|
+
await this._options.sendSignal(signalEvent.payload);
|
|
4030
3584
|
}
|
|
4031
3585
|
async getDetails() {
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
});
|
|
4038
|
-
return response.details;
|
|
4039
|
-
} catch (err) {
|
|
4040
|
-
return "bridge-svc unreachable";
|
|
4041
|
-
}
|
|
3586
|
+
return (await this._options.bridgeService.getDetails({
|
|
3587
|
+
proxyId: this._proxyId
|
|
3588
|
+
}, {
|
|
3589
|
+
timeout: RPC_TIMEOUT
|
|
3590
|
+
})).details;
|
|
4042
3591
|
}
|
|
4043
3592
|
async getStats() {
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
});
|
|
4050
|
-
return response.stats;
|
|
4051
|
-
} catch (err) {
|
|
4052
|
-
return {
|
|
4053
|
-
bytesSent: 0,
|
|
4054
|
-
bytesReceived: 0,
|
|
4055
|
-
packetsSent: 0,
|
|
4056
|
-
packetsReceived: 0,
|
|
4057
|
-
rawStats: "bridge-svc unreachable"
|
|
4058
|
-
};
|
|
4059
|
-
}
|
|
4060
|
-
}
|
|
4061
|
-
_raiseIfOpen(error) {
|
|
4062
|
-
if (this.isOpen) {
|
|
4063
|
-
this.errors.raise(error);
|
|
4064
|
-
} else {
|
|
4065
|
-
log14.info("error swallowed because transport was closed", {
|
|
4066
|
-
message: error.message
|
|
4067
|
-
}, {
|
|
4068
|
-
F: __dxlog_file15,
|
|
4069
|
-
L: 215,
|
|
4070
|
-
S: this,
|
|
4071
|
-
C: (f, a) => f(...a)
|
|
4072
|
-
});
|
|
4073
|
-
}
|
|
3593
|
+
return (await this._options.bridgeService.getStats({
|
|
3594
|
+
proxyId: this._proxyId
|
|
3595
|
+
}, {
|
|
3596
|
+
timeout: RPC_TIMEOUT
|
|
3597
|
+
})).stats;
|
|
4074
3598
|
}
|
|
4075
3599
|
/**
|
|
4076
3600
|
* Called when underlying proxy service becomes unavailable.
|
|
4077
3601
|
*/
|
|
3602
|
+
// TODO(burdon): Option on close method.
|
|
4078
3603
|
forceClose() {
|
|
4079
|
-
void this._serviceStream
|
|
3604
|
+
void this._serviceStream.close();
|
|
4080
3605
|
this.closed.emit();
|
|
3606
|
+
this._closed = true;
|
|
4081
3607
|
}
|
|
4082
3608
|
};
|
|
4083
|
-
var
|
|
3609
|
+
var SimplePeerTransportProxyFactory = class {
|
|
4084
3610
|
constructor() {
|
|
4085
3611
|
this._connections = /* @__PURE__ */ new Set();
|
|
4086
3612
|
}
|
|
@@ -4096,16 +3622,16 @@ var RtcTransportProxyFactory = class {
|
|
|
4096
3622
|
return this;
|
|
4097
3623
|
}
|
|
4098
3624
|
createTransport(options) {
|
|
4099
|
-
invariant13(this._bridgeService, "
|
|
3625
|
+
invariant13(this._bridgeService, "SimplePeerTransportProxyFactory is not ready to open connections", {
|
|
4100
3626
|
F: __dxlog_file15,
|
|
4101
|
-
L:
|
|
3627
|
+
L: 218,
|
|
4102
3628
|
S: this,
|
|
4103
3629
|
A: [
|
|
4104
3630
|
"this._bridgeService",
|
|
4105
|
-
"'
|
|
3631
|
+
"'SimplePeerTransportProxyFactory is not ready to open connections'"
|
|
4106
3632
|
]
|
|
4107
3633
|
});
|
|
4108
|
-
const transport = new
|
|
3634
|
+
const transport = new SimplePeerTransportProxy({
|
|
4109
3635
|
...options,
|
|
4110
3636
|
bridgeService: this._bridgeService
|
|
4111
3637
|
});
|
|
@@ -4117,222 +3643,496 @@ var RtcTransportProxyFactory = class {
|
|
|
4117
3643
|
var decodeError = (err) => {
|
|
4118
3644
|
const message = typeof err === "string" ? err : err.message;
|
|
4119
3645
|
if (message.includes("CONNECTION_RESET")) {
|
|
4120
|
-
return new
|
|
3646
|
+
return new ConnectionResetError3(message);
|
|
4121
3647
|
} else if (message.includes("TIMEOUT")) {
|
|
4122
3648
|
return new TimeoutError3(message);
|
|
3649
|
+
} else if (message.includes("PROTOCOL_ERROR")) {
|
|
3650
|
+
return new ProtocolError3(message);
|
|
4123
3651
|
} else if (message.includes("CONNECTIVITY_ERROR")) {
|
|
4124
|
-
return new
|
|
3652
|
+
return new ConnectivityError3(message);
|
|
3653
|
+
} else if (message.includes("UNKNOWN_PROTOCOL_ERROR")) {
|
|
3654
|
+
return new UnknownProtocolError3(message);
|
|
4125
3655
|
} else {
|
|
4126
3656
|
return typeof err === "string" ? new Error(err) : err;
|
|
4127
3657
|
}
|
|
4128
3658
|
};
|
|
4129
3659
|
|
|
4130
|
-
// packages/core/mesh/network-manager/src/transport/
|
|
4131
|
-
import { Duplex as Duplex2 } from "
|
|
4132
|
-
import {
|
|
3660
|
+
// packages/core/mesh/network-manager/src/transport/libdatachannel-transport.ts
|
|
3661
|
+
import { Duplex as Duplex2 } from "stream";
|
|
3662
|
+
import { Event as Event10, Trigger as Trigger3, synchronized as synchronized6 } from "@dxos/async";
|
|
3663
|
+
import { ErrorStream as ErrorStream6 } from "@dxos/debug";
|
|
4133
3664
|
import { invariant as invariant14 } from "@dxos/invariant";
|
|
4134
|
-
import { PublicKey as PublicKey11 } from "@dxos/keys";
|
|
4135
3665
|
import { log as log15 } from "@dxos/log";
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
var
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
3666
|
+
function _ts_decorate7(decorators, target, key, desc) {
|
|
3667
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3668
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3669
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3670
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3671
|
+
}
|
|
3672
|
+
var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/libdatachannel-transport.ts";
|
|
3673
|
+
var DATACHANNEL_LABEL = "dxos.mesh.transport";
|
|
3674
|
+
var MAX_BUFFERED_AMOUNT = 64 * 1024;
|
|
3675
|
+
var MAX_MESSAGE_SIZE = 64 * 1024;
|
|
3676
|
+
var createLibDataChannelTransportFactory = (webrtcConfig, iceProvider) => {
|
|
3677
|
+
return {
|
|
3678
|
+
createTransport: (options) => new LibDataChannelTransport({
|
|
3679
|
+
...options,
|
|
3680
|
+
webrtcConfig,
|
|
3681
|
+
iceProvider
|
|
3682
|
+
})
|
|
3683
|
+
};
|
|
3684
|
+
};
|
|
3685
|
+
var LibDataChannelTransport = class _LibDataChannelTransport {
|
|
3686
|
+
static {
|
|
3687
|
+
this._instanceCount = 0;
|
|
4143
3688
|
}
|
|
4144
|
-
|
|
4145
|
-
|
|
3689
|
+
constructor(_options) {
|
|
3690
|
+
this._options = _options;
|
|
3691
|
+
this._closed = false;
|
|
3692
|
+
this._connected = false;
|
|
3693
|
+
this._writeCallback = null;
|
|
3694
|
+
this._readyForCandidates = new Trigger3();
|
|
3695
|
+
this.closed = new Event10();
|
|
3696
|
+
this.connected = new Event10();
|
|
3697
|
+
this.errors = new ErrorStream6();
|
|
4146
3698
|
}
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
3699
|
+
get isOpen() {
|
|
3700
|
+
return !!this._peer && !this._closed;
|
|
3701
|
+
}
|
|
3702
|
+
async open() {
|
|
3703
|
+
if (this._closed) {
|
|
3704
|
+
this.errors.raise(new Error("connection already closed"));
|
|
3705
|
+
}
|
|
3706
|
+
const { RTCPeerConnection } = (await importESM("node-datachannel/polyfill")).default;
|
|
3707
|
+
const providedIceServers = await this._options.iceProvider?.getIceServers();
|
|
3708
|
+
if (!this._options.webrtcConfig) {
|
|
3709
|
+
this._options.webrtcConfig = {};
|
|
3710
|
+
}
|
|
3711
|
+
this._options.webrtcConfig.iceServers = [
|
|
3712
|
+
...this._options.webrtcConfig.iceServers ?? [],
|
|
3713
|
+
...providedIceServers ?? []
|
|
3714
|
+
];
|
|
3715
|
+
this._peer = new RTCPeerConnection(this._options.webrtcConfig);
|
|
3716
|
+
this._peer.onicecandidateerror = (event) => {
|
|
3717
|
+
log15.error("peer.onicecandidateerror", {
|
|
3718
|
+
event
|
|
3719
|
+
}, {
|
|
4151
3720
|
F: __dxlog_file16,
|
|
4152
|
-
L:
|
|
3721
|
+
L: 93,
|
|
4153
3722
|
S: this,
|
|
4154
3723
|
C: (f, a) => f(...a)
|
|
4155
3724
|
});
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
3725
|
+
};
|
|
3726
|
+
this._peer.onconnectionstatechange = (event) => {
|
|
3727
|
+
log15.debug("peer.onconnectionstatechange", {
|
|
3728
|
+
event,
|
|
3729
|
+
peerConnectionState: this._peer?.connectionState,
|
|
3730
|
+
transportConnectionState: this._connected
|
|
3731
|
+
}, {
|
|
3732
|
+
F: __dxlog_file16,
|
|
3733
|
+
L: 97,
|
|
3734
|
+
S: this,
|
|
3735
|
+
C: (f, a) => f(...a)
|
|
3736
|
+
});
|
|
3737
|
+
};
|
|
3738
|
+
this._peer.onicecandidate = async (event) => {
|
|
3739
|
+
log15.debug("peer.onicecandidate", {
|
|
3740
|
+
event
|
|
3741
|
+
}, {
|
|
3742
|
+
F: __dxlog_file16,
|
|
3743
|
+
L: 107,
|
|
3744
|
+
S: this,
|
|
3745
|
+
C: (f, a) => f(...a)
|
|
3746
|
+
});
|
|
3747
|
+
if (event.candidate) {
|
|
3748
|
+
try {
|
|
3749
|
+
await this._options.sendSignal({
|
|
3750
|
+
payload: {
|
|
3751
|
+
data: {
|
|
3752
|
+
type: "candidate",
|
|
3753
|
+
candidate: {
|
|
3754
|
+
candidate: event.candidate.candidate,
|
|
3755
|
+
// These fields never seem to be not null, but connecting to Chrome doesn't work if they are.
|
|
3756
|
+
sdpMLineIndex: event.candidate.sdpMLineIndex ?? 0,
|
|
3757
|
+
sdpMid: event.candidate.sdpMid ?? 0
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
4173
3760
|
}
|
|
4174
3761
|
});
|
|
4175
|
-
|
|
3762
|
+
} catch (err) {
|
|
3763
|
+
log15.info("signaling error", {
|
|
3764
|
+
err
|
|
3765
|
+
}, {
|
|
3766
|
+
F: __dxlog_file16,
|
|
3767
|
+
L: 124,
|
|
3768
|
+
S: this,
|
|
3769
|
+
C: (f, a) => f(...a)
|
|
3770
|
+
});
|
|
4176
3771
|
}
|
|
3772
|
+
}
|
|
3773
|
+
};
|
|
3774
|
+
if (this._options.initiator) {
|
|
3775
|
+
invariant14(this._peer, "not open", {
|
|
3776
|
+
F: __dxlog_file16,
|
|
3777
|
+
L: 130,
|
|
3778
|
+
S: this,
|
|
3779
|
+
A: [
|
|
3780
|
+
"this._peer",
|
|
3781
|
+
"'not open'"
|
|
3782
|
+
]
|
|
4177
3783
|
});
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
3784
|
+
this._peer.createOffer().then(async (offer) => {
|
|
3785
|
+
if (this._closed) {
|
|
3786
|
+
return;
|
|
3787
|
+
}
|
|
3788
|
+
if (this._peer?.connectionState !== "connecting") {
|
|
3789
|
+
log15.error("peer not connecting", {
|
|
3790
|
+
peer: this._peer
|
|
3791
|
+
}, {
|
|
3792
|
+
F: __dxlog_file16,
|
|
3793
|
+
L: 141,
|
|
3794
|
+
S: this,
|
|
3795
|
+
C: (f, a) => f(...a)
|
|
4189
3796
|
});
|
|
3797
|
+
this.errors.raise(new Error("invalid state: peer is initiator, but other peer not in state connecting"));
|
|
4190
3798
|
}
|
|
3799
|
+
log15.debug("creating offer", {
|
|
3800
|
+
peer: this._peer,
|
|
3801
|
+
offer
|
|
3802
|
+
}, {
|
|
3803
|
+
F: __dxlog_file16,
|
|
3804
|
+
L: 145,
|
|
3805
|
+
S: this,
|
|
3806
|
+
C: (f, a) => f(...a)
|
|
3807
|
+
});
|
|
3808
|
+
await this._peer.setLocalDescription(offer);
|
|
3809
|
+
await this._options.sendSignal({
|
|
3810
|
+
payload: {
|
|
3811
|
+
data: {
|
|
3812
|
+
type: offer.type,
|
|
3813
|
+
sdp: offer.sdp
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
});
|
|
3817
|
+
}).catch((err) => {
|
|
3818
|
+
this.errors.raise(err);
|
|
4191
3819
|
});
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
3820
|
+
this._handleChannel(this._peer.createDataChannel(DATACHANNEL_LABEL));
|
|
3821
|
+
log15.debug("created data channel", void 0, {
|
|
3822
|
+
F: __dxlog_file16,
|
|
3823
|
+
L: 155,
|
|
3824
|
+
S: this,
|
|
3825
|
+
C: (f, a) => f(...a)
|
|
3826
|
+
});
|
|
3827
|
+
this._peer.ondatachannel = () => {
|
|
3828
|
+
this.errors.raise(new Error("unexpected ondatachannel event for initiator"));
|
|
4197
3829
|
};
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
3830
|
+
} else {
|
|
3831
|
+
this._peer.ondatachannel = (event) => {
|
|
3832
|
+
log15.debug("peer.ondatachannel (non-initiator)", {
|
|
3833
|
+
event
|
|
3834
|
+
}, {
|
|
3835
|
+
F: __dxlog_file16,
|
|
3836
|
+
L: 161,
|
|
3837
|
+
S: this,
|
|
3838
|
+
C: (f, a) => f(...a)
|
|
3839
|
+
});
|
|
3840
|
+
if (event.channel.label !== DATACHANNEL_LABEL) {
|
|
3841
|
+
this.errors.raise(new Error(`unexpected channel label ${event.channel.label}`));
|
|
3842
|
+
}
|
|
3843
|
+
this._handleChannel(event.channel);
|
|
3844
|
+
};
|
|
3845
|
+
}
|
|
3846
|
+
_LibDataChannelTransport._instanceCount++;
|
|
3847
|
+
}
|
|
3848
|
+
async close() {
|
|
3849
|
+
await this._close();
|
|
3850
|
+
if (--_LibDataChannelTransport._instanceCount === 0) {
|
|
3851
|
+
(await importESM("node-datachannel")).cleanup();
|
|
3852
|
+
}
|
|
3853
|
+
}
|
|
3854
|
+
async _close() {
|
|
3855
|
+
if (this._closed) {
|
|
3856
|
+
return;
|
|
3857
|
+
}
|
|
3858
|
+
await this._disconnectStreams();
|
|
3859
|
+
try {
|
|
3860
|
+
this._peer?.close();
|
|
3861
|
+
} catch (err) {
|
|
3862
|
+
this.errors.raise(err);
|
|
3863
|
+
}
|
|
3864
|
+
this._peer = void 0;
|
|
3865
|
+
this._closed = true;
|
|
3866
|
+
this.closed.emit();
|
|
3867
|
+
}
|
|
3868
|
+
/**
|
|
3869
|
+
* Handle data channel events.
|
|
3870
|
+
*/
|
|
3871
|
+
_handleChannel(dataChannel) {
|
|
3872
|
+
this._channel = dataChannel;
|
|
3873
|
+
this._channel.onopen = () => {
|
|
3874
|
+
log15.debug("channel.onopen", void 0, {
|
|
3875
|
+
F: __dxlog_file16,
|
|
3876
|
+
L: 206,
|
|
3877
|
+
S: this,
|
|
3878
|
+
C: (f, a) => f(...a)
|
|
4204
3879
|
});
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
3880
|
+
const duplex = new Duplex2({
|
|
3881
|
+
read: () => {
|
|
3882
|
+
},
|
|
3883
|
+
write: async (chunk, encoding, callback) => {
|
|
3884
|
+
if (chunk.length > MAX_MESSAGE_SIZE) {
|
|
3885
|
+
this.errors.raise(new Error(`message too large: ${chunk.length} > ${MAX_MESSAGE_SIZE}`));
|
|
3886
|
+
}
|
|
3887
|
+
try {
|
|
3888
|
+
dataChannel.send(chunk);
|
|
3889
|
+
} catch (err) {
|
|
3890
|
+
this.errors.raise(err);
|
|
3891
|
+
await this._close();
|
|
3892
|
+
}
|
|
3893
|
+
if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {
|
|
3894
|
+
if (this._writeCallback !== null) {
|
|
3895
|
+
log15.error("consumer trying to write before we are ready for more data", void 0, {
|
|
3896
|
+
F: __dxlog_file16,
|
|
3897
|
+
L: 223,
|
|
3898
|
+
S: this,
|
|
3899
|
+
C: (f, a) => f(...a)
|
|
3900
|
+
});
|
|
3901
|
+
}
|
|
3902
|
+
this._writeCallback = callback;
|
|
3903
|
+
} else {
|
|
3904
|
+
callback();
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
4209
3907
|
});
|
|
4210
|
-
this.
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
3908
|
+
duplex.pipe(this._options.stream).pipe(duplex);
|
|
3909
|
+
this._stream = duplex;
|
|
3910
|
+
this._connected = true;
|
|
3911
|
+
this.connected.emit();
|
|
3912
|
+
};
|
|
3913
|
+
this._channel.onclose = async (err) => {
|
|
3914
|
+
log15.info("channel.onclose", {
|
|
3915
|
+
err
|
|
3916
|
+
}, {
|
|
3917
|
+
F: __dxlog_file16,
|
|
3918
|
+
L: 239,
|
|
3919
|
+
S: this,
|
|
3920
|
+
C: (f, a) => f(...a)
|
|
4215
3921
|
});
|
|
4216
|
-
|
|
4217
|
-
}
|
|
3922
|
+
await this._close();
|
|
3923
|
+
};
|
|
3924
|
+
this._channel.onerror = async (err) => {
|
|
3925
|
+
this.errors.raise(new Error("channel error: " + err.toString()));
|
|
3926
|
+
await this._close();
|
|
3927
|
+
};
|
|
3928
|
+
this._channel.onbufferedamountlow = () => {
|
|
3929
|
+
const cb = this._writeCallback;
|
|
3930
|
+
this._writeCallback = null;
|
|
3931
|
+
cb?.();
|
|
3932
|
+
};
|
|
3933
|
+
this._channel.onmessage = (event) => {
|
|
3934
|
+
let data = event.data;
|
|
3935
|
+
if (data instanceof ArrayBuffer) {
|
|
3936
|
+
data = Buffer2.from(data);
|
|
3937
|
+
}
|
|
3938
|
+
this._stream.push(data);
|
|
3939
|
+
};
|
|
4218
3940
|
}
|
|
4219
|
-
async
|
|
4220
|
-
|
|
4221
|
-
invariant14(transport, void 0, {
|
|
3941
|
+
async onSignal(signal) {
|
|
3942
|
+
invariant14(this._peer, "not open", {
|
|
4222
3943
|
F: __dxlog_file16,
|
|
4223
|
-
L:
|
|
3944
|
+
L: 265,
|
|
4224
3945
|
S: this,
|
|
4225
3946
|
A: [
|
|
4226
|
-
"
|
|
4227
|
-
""
|
|
3947
|
+
"this._peer",
|
|
3948
|
+
"'not open'"
|
|
4228
3949
|
]
|
|
4229
3950
|
});
|
|
4230
|
-
|
|
3951
|
+
try {
|
|
3952
|
+
const data = signal.payload.data;
|
|
3953
|
+
switch (data.type) {
|
|
3954
|
+
case "offer": {
|
|
3955
|
+
if (this._peer.connectionState !== "new") {
|
|
3956
|
+
log15.error("received offer but peer not in state new", {
|
|
3957
|
+
peer: this._peer
|
|
3958
|
+
}, {
|
|
3959
|
+
F: __dxlog_file16,
|
|
3960
|
+
L: 272,
|
|
3961
|
+
S: this,
|
|
3962
|
+
C: (f, a) => f(...a)
|
|
3963
|
+
});
|
|
3964
|
+
this.errors.raise(new Error("invalid signalling state: received offer when peer is not in state new"));
|
|
3965
|
+
break;
|
|
3966
|
+
}
|
|
3967
|
+
try {
|
|
3968
|
+
await this._peer.setRemoteDescription({
|
|
3969
|
+
type: data.type,
|
|
3970
|
+
sdp: data.sdp
|
|
3971
|
+
});
|
|
3972
|
+
const answer = await this._peer.createAnswer();
|
|
3973
|
+
await this._peer.setLocalDescription(answer);
|
|
3974
|
+
await this._options.sendSignal({
|
|
3975
|
+
payload: {
|
|
3976
|
+
data: {
|
|
3977
|
+
type: answer.type,
|
|
3978
|
+
sdp: answer.sdp
|
|
3979
|
+
}
|
|
3980
|
+
}
|
|
3981
|
+
});
|
|
3982
|
+
this._readyForCandidates.wake();
|
|
3983
|
+
} catch (err) {
|
|
3984
|
+
log15.error("cannot handle offer from signalling server", {
|
|
3985
|
+
err
|
|
3986
|
+
}, {
|
|
3987
|
+
F: __dxlog_file16,
|
|
3988
|
+
L: 284,
|
|
3989
|
+
S: this,
|
|
3990
|
+
C: (f, a) => f(...a)
|
|
3991
|
+
});
|
|
3992
|
+
this.errors.raise(new Error("error handling offer"));
|
|
3993
|
+
}
|
|
3994
|
+
break;
|
|
3995
|
+
}
|
|
3996
|
+
case "answer":
|
|
3997
|
+
try {
|
|
3998
|
+
await this._peer.setRemoteDescription({
|
|
3999
|
+
type: data.type,
|
|
4000
|
+
sdp: data.sdp
|
|
4001
|
+
});
|
|
4002
|
+
this._readyForCandidates.wake();
|
|
4003
|
+
} catch (err) {
|
|
4004
|
+
log15.error("cannot handle answer from signalling server", {
|
|
4005
|
+
err
|
|
4006
|
+
}, {
|
|
4007
|
+
F: __dxlog_file16,
|
|
4008
|
+
L: 295,
|
|
4009
|
+
S: this,
|
|
4010
|
+
C: (f, a) => f(...a)
|
|
4011
|
+
});
|
|
4012
|
+
this.errors.raise(new Error("error handling answer"));
|
|
4013
|
+
}
|
|
4014
|
+
break;
|
|
4015
|
+
case "candidate":
|
|
4016
|
+
await this._readyForCandidates.wait();
|
|
4017
|
+
await this._peer.addIceCandidate({
|
|
4018
|
+
candidate: data.candidate.candidate
|
|
4019
|
+
});
|
|
4020
|
+
break;
|
|
4021
|
+
default:
|
|
4022
|
+
log15.error("unhandled signal type", {
|
|
4023
|
+
type: data.type,
|
|
4024
|
+
signal
|
|
4025
|
+
}, {
|
|
4026
|
+
F: __dxlog_file16,
|
|
4027
|
+
L: 306,
|
|
4028
|
+
S: this,
|
|
4029
|
+
C: (f, a) => f(...a)
|
|
4030
|
+
});
|
|
4031
|
+
this.errors.raise(new Error(`unhandled signal type ${data.type}`));
|
|
4032
|
+
}
|
|
4033
|
+
} catch (err) {
|
|
4034
|
+
log15.catch(err, void 0, {
|
|
4035
|
+
F: __dxlog_file16,
|
|
4036
|
+
L: 310,
|
|
4037
|
+
S: this,
|
|
4038
|
+
C: (f, a) => f(...a)
|
|
4039
|
+
});
|
|
4040
|
+
}
|
|
4231
4041
|
}
|
|
4232
|
-
async getDetails(
|
|
4233
|
-
const
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4042
|
+
async getDetails() {
|
|
4043
|
+
const stats = await this._getStats();
|
|
4044
|
+
const rc = stats?.remoteCandidate;
|
|
4045
|
+
if (!rc) {
|
|
4046
|
+
return "unavailable";
|
|
4047
|
+
}
|
|
4048
|
+
if (rc.candidateType === "relay") {
|
|
4049
|
+
return `${rc.ip}:${rc.port} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
|
|
4050
|
+
}
|
|
4051
|
+
return `${rc.ip}:${rc.port} ${rc.candidateType}`;
|
|
4052
|
+
}
|
|
4053
|
+
async getStats() {
|
|
4054
|
+
const stats = await this._getStats();
|
|
4055
|
+
if (!stats) {
|
|
4056
|
+
return {
|
|
4057
|
+
bytesSent: 0,
|
|
4058
|
+
bytesReceived: 0,
|
|
4059
|
+
packetsSent: 0,
|
|
4060
|
+
packetsReceived: 0,
|
|
4061
|
+
rawStats: {}
|
|
4062
|
+
};
|
|
4063
|
+
}
|
|
4243
4064
|
return {
|
|
4244
|
-
|
|
4065
|
+
bytesSent: stats.transport.bytesSent,
|
|
4066
|
+
bytesReceived: stats.transport.bytesReceived,
|
|
4067
|
+
packetsSent: 0,
|
|
4068
|
+
packetsReceived: 0,
|
|
4069
|
+
rawStats: stats.raw
|
|
4245
4070
|
};
|
|
4246
4071
|
}
|
|
4247
|
-
async
|
|
4248
|
-
|
|
4249
|
-
invariant14(transport, void 0, {
|
|
4072
|
+
async _getStats() {
|
|
4073
|
+
invariant14(this._peer, "not open", {
|
|
4250
4074
|
F: __dxlog_file16,
|
|
4251
|
-
L:
|
|
4075
|
+
L: 350,
|
|
4252
4076
|
S: this,
|
|
4253
4077
|
A: [
|
|
4254
|
-
"
|
|
4255
|
-
""
|
|
4078
|
+
"this._peer",
|
|
4079
|
+
"'not open'"
|
|
4256
4080
|
]
|
|
4257
4081
|
});
|
|
4082
|
+
const stats = await this._peer.getStats();
|
|
4083
|
+
const statsEntries = Array.from(stats.entries());
|
|
4084
|
+
const transport = statsEntries.filter((s) => s[1].type === "transport")[0][1];
|
|
4085
|
+
const candidatePair = statsEntries.filter((s) => s[0] === transport.selectedCandidatePairId);
|
|
4086
|
+
let selectedCandidatePair;
|
|
4087
|
+
let remoteCandidate;
|
|
4088
|
+
if (candidatePair.length > 0) {
|
|
4089
|
+
selectedCandidatePair = candidatePair[0][1];
|
|
4090
|
+
remoteCandidate = statsEntries.filter((s) => s[0] === selectedCandidatePair.remoteCandidateId)[0][1];
|
|
4091
|
+
}
|
|
4258
4092
|
return {
|
|
4259
|
-
|
|
4093
|
+
transport,
|
|
4094
|
+
selectedCandidatePair,
|
|
4095
|
+
remoteCandidate,
|
|
4096
|
+
raw: Object.fromEntries(stats)
|
|
4260
4097
|
};
|
|
4261
4098
|
}
|
|
4262
|
-
async
|
|
4263
|
-
|
|
4264
|
-
invariant14(transport, void 0, {
|
|
4265
|
-
F: __dxlog_file16,
|
|
4266
|
-
L: 142,
|
|
4267
|
-
S: this,
|
|
4268
|
-
A: [
|
|
4269
|
-
"transport",
|
|
4270
|
-
""
|
|
4271
|
-
]
|
|
4272
|
-
});
|
|
4273
|
-
const bufferHasSpace = transport.connectorStream.push(payload);
|
|
4274
|
-
if (!bufferHasSpace) {
|
|
4275
|
-
await new Promise((resolve) => {
|
|
4276
|
-
transport.writeProcessedCallbacks.push(resolve);
|
|
4277
|
-
});
|
|
4278
|
-
}
|
|
4099
|
+
async _disconnectStreams() {
|
|
4100
|
+
this._options.stream.unpipe?.(this._stream)?.unpipe?.(this._options.stream);
|
|
4279
4101
|
}
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4102
|
+
};
|
|
4103
|
+
_ts_decorate7([
|
|
4104
|
+
synchronized6
|
|
4105
|
+
], LibDataChannelTransport.prototype, "_close", null);
|
|
4106
|
+
var importESM = Function("path", "return import(path)");
|
|
4107
|
+
|
|
4108
|
+
// packages/core/mesh/network-manager/src/transport/tcp-transport.browser.ts
|
|
4109
|
+
import { Event as Event11 } from "@dxos/async";
|
|
4110
|
+
import { ErrorStream as ErrorStream7 } from "@dxos/debug";
|
|
4111
|
+
var TcpTransportFactory = {
|
|
4112
|
+
createTransport: () => new TcpTransport()
|
|
4113
|
+
};
|
|
4114
|
+
var TcpTransport = class {
|
|
4115
|
+
constructor() {
|
|
4116
|
+
this.closed = new Event11();
|
|
4117
|
+
this.connected = new Event11();
|
|
4118
|
+
this.errors = new ErrorStream7();
|
|
4287
4119
|
}
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
});
|
|
4304
|
-
}
|
|
4305
|
-
try {
|
|
4306
|
-
transport.connectorStream.end();
|
|
4307
|
-
} catch (error) {
|
|
4308
|
-
log15.warn("connectorStream close error", {
|
|
4309
|
-
message: error?.message
|
|
4310
|
-
}, {
|
|
4311
|
-
F: __dxlog_file16,
|
|
4312
|
-
L: 177,
|
|
4313
|
-
S: this,
|
|
4314
|
-
C: (f, a) => f(...a)
|
|
4315
|
-
});
|
|
4316
|
-
}
|
|
4317
|
-
log15("closed", void 0, {
|
|
4318
|
-
F: __dxlog_file16,
|
|
4319
|
-
L: 179,
|
|
4320
|
-
S: this,
|
|
4321
|
-
C: (f, a) => f(...a)
|
|
4322
|
-
});
|
|
4120
|
+
get isOpen() {
|
|
4121
|
+
return true;
|
|
4122
|
+
}
|
|
4123
|
+
async open() {
|
|
4124
|
+
}
|
|
4125
|
+
async close() {
|
|
4126
|
+
}
|
|
4127
|
+
async onSignal() {
|
|
4128
|
+
throw new Error("Method not implemented.");
|
|
4129
|
+
}
|
|
4130
|
+
async getStats() {
|
|
4131
|
+
throw new Error("Method not implemented.");
|
|
4132
|
+
}
|
|
4133
|
+
async getDetails() {
|
|
4134
|
+
throw new Error("Method not implemented.");
|
|
4323
4135
|
}
|
|
4324
|
-
};
|
|
4325
|
-
var createStateUpdater = (next) => {
|
|
4326
|
-
return (state, err) => {
|
|
4327
|
-
next({
|
|
4328
|
-
connection: {
|
|
4329
|
-
state,
|
|
4330
|
-
...err ? {
|
|
4331
|
-
error: err.message
|
|
4332
|
-
} : void 0
|
|
4333
|
-
}
|
|
4334
|
-
});
|
|
4335
|
-
};
|
|
4336
4136
|
};
|
|
4337
4137
|
|
|
4338
4138
|
// packages/core/mesh/network-manager/src/wire-protocol.ts
|
|
@@ -4360,6 +4160,7 @@ var createTeleportProtocolFactory = (onConnection, defaultParams) => {
|
|
|
4360
4160
|
};
|
|
4361
4161
|
|
|
4362
4162
|
export {
|
|
4163
|
+
process,
|
|
4363
4164
|
ConnectionState,
|
|
4364
4165
|
Connection,
|
|
4365
4166
|
createIceProvider,
|
|
@@ -4377,10 +4178,15 @@ export {
|
|
|
4377
4178
|
MemoryTransportFactory,
|
|
4378
4179
|
MemoryTransport,
|
|
4379
4180
|
TransportKind,
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4181
|
+
createSimplePeerTransportFactory,
|
|
4182
|
+
SimplePeerTransport,
|
|
4183
|
+
SimplePeerTransportService,
|
|
4184
|
+
SimplePeerTransportProxy,
|
|
4185
|
+
SimplePeerTransportProxyFactory,
|
|
4186
|
+
createLibDataChannelTransportFactory,
|
|
4187
|
+
LibDataChannelTransport,
|
|
4188
|
+
TcpTransportFactory,
|
|
4189
|
+
TcpTransport,
|
|
4384
4190
|
createTeleportProtocolFactory
|
|
4385
4191
|
};
|
|
4386
|
-
//# sourceMappingURL=chunk-
|
|
4192
|
+
//# sourceMappingURL=chunk-XYSYUN63.mjs.map
|