@dxos/network-manager 0.6.13-staging.1e988a3 → 0.6.14-main.1366248
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-XYSYUN63.mjs → chunk-UEVA7BFW.mjs} +1323 -1102
- package/dist/lib/browser/chunk-UEVA7BFW.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +9 -19
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +30 -37
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/transport/tcp/index.mjs +38 -0
- package/dist/lib/browser/transport/tcp/index.mjs.map +7 -0
- package/dist/lib/node/{chunk-4YAYC7WN.cjs → chunk-LK5D44SA.cjs} +1336 -1239
- package/dist/lib/node/chunk-LK5D44SA.cjs.map +7 -0
- package/dist/lib/node/index.cjs +27 -37
- package/dist/lib/node/index.cjs.map +2 -2
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +34 -38
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/lib/node/transport/tcp/index.cjs +191 -0
- package/dist/lib/node/transport/tcp/index.cjs.map +7 -0
- package/dist/lib/node-esm/chunk-Y5TD36KR.mjs +4413 -0
- package/dist/lib/node-esm/chunk-Y5TD36KR.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +50 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/testing/index.mjs +285 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/lib/node-esm/transport/tcp/index.mjs +159 -0
- package/dist/lib/node-esm/transport/tcp/index.mjs.map +7 -0
- package/dist/types/src/network-manager.d.ts +2 -1
- package/dist/types/src/network-manager.d.ts.map +1 -1
- package/dist/types/src/signal/ice.d.ts.map +1 -1
- package/dist/types/src/signal/integration.node.test.d.ts +2 -0
- package/dist/types/src/signal/integration.node.test.d.ts.map +1 -0
- package/dist/types/src/signal/swarm-messenger.node.test.d.ts +2 -0
- package/dist/types/src/signal/swarm-messenger.node.test.d.ts.map +1 -0
- package/dist/types/src/swarm/connection.d.ts.map +1 -1
- package/dist/types/src/swarm/peer.d.ts.map +1 -1
- package/dist/types/src/swarm/swarm.d.ts +2 -1
- package/dist/types/src/swarm/swarm.d.ts.map +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/testing/test-wire-protocol.d.ts +1 -2
- package/dist/types/src/testing/test-wire-protocol.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.node.test.d.ts +2 -0
- package/dist/types/src/tests/tcp-transport.node.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 +1 -5
- package/dist/types/src/transport/index.d.ts.map +1 -1
- 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/tcp/index.d.ts +2 -0
- package/dist/types/src/transport/tcp/index.d.ts.map +1 -0
- package/dist/types/src/transport/{tcp-transport.browser.d.ts → tcp/tcp-transport.browser.d.ts} +3 -3
- package/dist/types/src/transport/tcp/tcp-transport.browser.d.ts.map +1 -0
- package/dist/types/src/transport/{tcp-transport.d.ts → tcp/tcp-transport.d.ts} +3 -3
- package/dist/types/src/transport/tcp/tcp-transport.d.ts.map +1 -0
- package/dist/types/src/transport/transport.d.ts +7 -6
- package/dist/types/src/transport/transport.d.ts.map +1 -1
- package/dist/types/src/transport/webrtc/index.d.ts +4 -0
- package/dist/types/src/transport/webrtc/index.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts +14 -0
- package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts +68 -0
- package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts +33 -0
- package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts +2 -0
- package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts +4 -0
- package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts.map +1 -0
- package/dist/types/src/transport/{simplepeer-transport-proxy.d.ts → webrtc/rtc-transport-proxy.d.ts} +10 -12
- package/dist/types/src/transport/webrtc/rtc-transport-proxy.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts +2 -0
- package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts.map +1 -0
- package/dist/types/src/transport/{simplepeer-transport-service.d.ts → webrtc/rtc-transport-service.d.ts} +9 -7
- package/dist/types/src/transport/webrtc/rtc-transport-service.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts +4 -0
- package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts +2 -0
- package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/test-utils.d.ts +5 -0
- package/dist/types/src/transport/webrtc/test-utils.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/utils.d.ts +3 -0
- package/dist/types/src/transport/webrtc/utils.d.ts.map +1 -0
- package/package.json +53 -36
- package/src/network-manager.ts +5 -13
- package/src/signal/ice.test.ts +1 -3
- package/src/signal/ice.ts +6 -1
- package/src/signal/{integration.test.ts → integration.node.test.ts} +9 -15
- package/src/signal/{swarm-messenger.test.ts → swarm-messenger.node.test.ts} +13 -23
- package/src/swarm/connection-limiter.test.ts +3 -6
- package/src/swarm/connection.test.ts +63 -38
- package/src/swarm/connection.ts +7 -7
- package/src/swarm/peer.ts +4 -1
- package/src/swarm/swarm.test.ts +10 -12
- package/src/swarm/swarm.ts +16 -3
- package/src/testing/test-builder.ts +14 -29
- package/src/testing/test-wire-protocol.ts +7 -8
- package/src/tests/basic-test-suite.ts +32 -31
- package/src/tests/memory-transport.test.ts +40 -42
- package/src/tests/property-test-suite.ts +21 -22
- package/src/tests/tcp-transport.node.test.ts +65 -0
- package/src/tests/utils.ts +3 -2
- package/src/tests/webrtc-transport.test.ts +10 -10
- package/src/transport/index.ts +1 -5
- package/src/transport/memory-transport.ts +2 -0
- package/src/transport/tcp/index.ts +5 -0
- package/src/transport/{tcp-transport.browser.ts → tcp/tcp-transport.browser.ts} +7 -3
- package/src/transport/{tcp-transport.ts → tcp/tcp-transport.ts} +3 -1
- package/src/transport/transport.ts +8 -7
- package/src/transport/webrtc/index.ts +7 -0
- package/src/transport/webrtc/rtc-connection-factory.ts +82 -0
- package/src/transport/webrtc/rtc-peer-connection.ts +472 -0
- package/src/transport/webrtc/rtc-transport-channel.test.ts +176 -0
- package/src/transport/webrtc/rtc-transport-channel.ts +195 -0
- package/src/transport/webrtc/rtc-transport-factory.ts +28 -0
- package/src/transport/webrtc/rtc-transport-proxy.test.ts +413 -0
- package/src/transport/webrtc/rtc-transport-proxy.ts +264 -0
- package/src/transport/webrtc/rtc-transport-service.ts +192 -0
- package/src/transport/webrtc/rtc-transport-stats.ts +67 -0
- package/src/transport/webrtc/rtc-transport.test.ts +210 -0
- package/src/transport/webrtc/test-utils.ts +22 -0
- package/src/transport/webrtc/utils.ts +36 -0
- package/src/typings.d.ts +8 -2
- package/dist/lib/browser/chunk-XYSYUN63.mjs.map +0 -7
- package/dist/lib/node/chunk-4YAYC7WN.cjs.map +0 -7
- package/dist/types/src/signal/integration.test.d.ts +0 -2
- package/dist/types/src/signal/integration.test.d.ts.map +0 -1
- package/dist/types/src/signal/swarm-messenger.test.d.ts +0 -2
- package/dist/types/src/signal/swarm-messenger.test.d.ts.map +0 -1
- package/dist/types/src/tests/tcp-transport.test.d.ts +0 -2
- package/dist/types/src/tests/tcp-transport.test.d.ts.map +0 -1
- package/dist/types/src/transport/libdatachannel-transport.d.ts +0 -42
- package/dist/types/src/transport/libdatachannel-transport.d.ts.map +0 -1
- package/dist/types/src/transport/libdatachannel-transport.test.d.ts +0 -2
- package/dist/types/src/transport/libdatachannel-transport.test.d.ts.map +0 -1
- package/dist/types/src/transport/memory-transport.test.d.ts +0 -2
- package/dist/types/src/transport/memory-transport.test.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-simple-peer.d.ts +0 -2
- package/dist/types/src/transport/simplepeer-simple-peer.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts +0 -2
- package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-transport-proxy.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-transport-service.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-transport.d.ts +0 -36
- package/dist/types/src/transport/simplepeer-transport.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-transport.test.d.ts +0 -2
- package/dist/types/src/transport/simplepeer-transport.test.d.ts.map +0 -1
- package/dist/types/src/transport/tcp-transport.browser.d.ts.map +0 -1
- package/dist/types/src/transport/tcp-transport.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc.d.ts +0 -6
- package/dist/types/src/transport/webrtc.d.ts.map +0 -1
- package/src/globals.d.ts +0 -7
- package/src/tests/tcp-transport.test.ts +0 -67
- package/src/transport/libdatachannel-transport.test.ts +0 -100
- package/src/transport/libdatachannel-transport.ts +0 -376
- package/src/transport/memory-transport.test.ts +0 -74
- package/src/transport/simplepeer-simple-peer.ts +0 -26
- package/src/transport/simplepeer-transport-proxy-test.ts +0 -181
- package/src/transport/simplepeer-transport-proxy.ts +0 -246
- package/src/transport/simplepeer-transport-service.ts +0 -160
- package/src/transport/simplepeer-transport.test.ts +0 -61
- package/src/transport/simplepeer-transport.ts +0 -250
- package/src/transport/webrtc.ts +0 -15
|
@@ -1,17 +1,4 @@
|
|
|
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
|
|
10
|
-
import {
|
|
11
|
-
global,
|
|
12
|
-
Buffer as Buffer2,
|
|
13
|
-
process
|
|
14
|
-
} from "@dxos/node-std/inject-globals";
|
|
15
2
|
|
|
16
3
|
// packages/core/mesh/network-manager/src/swarm/connection.ts
|
|
17
4
|
import { DeferredTask, Event, sleep, scheduleTask, scheduleTaskInterval, synchronized, Trigger } from "@dxos/async";
|
|
@@ -20,7 +7,7 @@ import { ErrorStream } from "@dxos/debug";
|
|
|
20
7
|
import { invariant } from "@dxos/invariant";
|
|
21
8
|
import { PublicKey } from "@dxos/keys";
|
|
22
9
|
import { log, logInfo } from "@dxos/log";
|
|
23
|
-
import { CancelledError, ProtocolError, ConnectionResetError, ConnectivityError, TimeoutError,
|
|
10
|
+
import { CancelledError, ProtocolError, ConnectionResetError, ConnectivityError, TimeoutError, trace } from "@dxos/protocols";
|
|
24
11
|
function _ts_decorate(decorators, target, key, desc) {
|
|
25
12
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
26
13
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -56,11 +43,11 @@ var Connection = class {
|
|
|
56
43
|
this._callbacks = _callbacks;
|
|
57
44
|
this._ctx = new Context(void 0, {
|
|
58
45
|
F: __dxlog_file,
|
|
59
|
-
L:
|
|
46
|
+
L: 100
|
|
60
47
|
});
|
|
61
48
|
this.connectedTimeoutContext = new Context(void 0, {
|
|
62
49
|
F: __dxlog_file,
|
|
63
|
-
L:
|
|
50
|
+
L: 101
|
|
64
51
|
});
|
|
65
52
|
this._protocolClosed = new Trigger();
|
|
66
53
|
this._transportClosed = new Trigger();
|
|
@@ -83,7 +70,7 @@ var Connection = class {
|
|
|
83
70
|
initiator: this.initiator
|
|
84
71
|
}, {
|
|
85
72
|
F: __dxlog_file,
|
|
86
|
-
L:
|
|
73
|
+
L: 137,
|
|
87
74
|
S: this,
|
|
88
75
|
C: (f, a) => f(...a)
|
|
89
76
|
});
|
|
@@ -106,7 +93,7 @@ var Connection = class {
|
|
|
106
93
|
async openConnection() {
|
|
107
94
|
invariant(this._state === "INITIAL", "Invalid state.", {
|
|
108
95
|
F: __dxlog_file,
|
|
109
|
-
L:
|
|
96
|
+
L: 167,
|
|
110
97
|
S: this,
|
|
111
98
|
A: [
|
|
112
99
|
"this._state === ConnectionState.INITIAL",
|
|
@@ -117,7 +104,7 @@ var Connection = class {
|
|
|
117
104
|
id: this._instanceId
|
|
118
105
|
}), {
|
|
119
106
|
F: __dxlog_file,
|
|
120
|
-
L:
|
|
107
|
+
L: 168,
|
|
121
108
|
S: this,
|
|
122
109
|
C: (f, a) => f(...a)
|
|
123
110
|
});
|
|
@@ -129,7 +116,7 @@ var Connection = class {
|
|
|
129
116
|
initiator: this.initiator
|
|
130
117
|
}, {
|
|
131
118
|
F: __dxlog_file,
|
|
132
|
-
L:
|
|
119
|
+
L: 169,
|
|
133
120
|
S: this,
|
|
134
121
|
C: (f, a) => f(...a)
|
|
135
122
|
});
|
|
@@ -140,7 +127,7 @@ var Connection = class {
|
|
|
140
127
|
this._protocol.stream.on("close", () => {
|
|
141
128
|
log("protocol stream closed", void 0, {
|
|
142
129
|
F: __dxlog_file,
|
|
143
|
-
L:
|
|
130
|
+
L: 186,
|
|
144
131
|
S: this,
|
|
145
132
|
C: (f, a) => f(...a)
|
|
146
133
|
});
|
|
@@ -150,7 +137,7 @@ var Connection = class {
|
|
|
150
137
|
scheduleTask(this.connectedTimeoutContext, async () => {
|
|
151
138
|
log.info(`timeout waiting ${TRANSPORT_CONNECTION_TIMEOUT / 1e3}s for transport to connect, aborting`, void 0, {
|
|
152
139
|
F: __dxlog_file,
|
|
153
|
-
L:
|
|
140
|
+
L: 194,
|
|
154
141
|
S: this,
|
|
155
142
|
C: (f, a) => f(...a)
|
|
156
143
|
});
|
|
@@ -158,7 +145,7 @@ var Connection = class {
|
|
|
158
145
|
}, TRANSPORT_CONNECTION_TIMEOUT);
|
|
159
146
|
invariant(!this._transport, void 0, {
|
|
160
147
|
F: __dxlog_file,
|
|
161
|
-
L:
|
|
148
|
+
L: 202,
|
|
162
149
|
S: this,
|
|
163
150
|
A: [
|
|
164
151
|
"!this._transport",
|
|
@@ -166,12 +153,14 @@ var Connection = class {
|
|
|
166
153
|
]
|
|
167
154
|
});
|
|
168
155
|
this._transport = this._transportFactory.createTransport({
|
|
156
|
+
ownPeerKey: this.localInfo.peerKey,
|
|
157
|
+
remotePeerKey: this.remoteInfo.peerKey,
|
|
158
|
+
topic: this.topic.toHex(),
|
|
169
159
|
initiator: this.initiator,
|
|
170
160
|
stream: this._protocol.stream,
|
|
171
161
|
sendSignal: async (signal) => this._sendSignal(signal),
|
|
172
162
|
sessionId: this.sessionId
|
|
173
163
|
});
|
|
174
|
-
await this._transport.open();
|
|
175
164
|
this._transport.connected.once(async () => {
|
|
176
165
|
this._changeState("CONNECTED");
|
|
177
166
|
await this.connectedTimeoutContext.dispose();
|
|
@@ -208,7 +197,7 @@ var Connection = class {
|
|
|
208
197
|
S: this,
|
|
209
198
|
C: (f, a) => f(...a)
|
|
210
199
|
});
|
|
211
|
-
this.abort().catch((err2) => this.errors.raise(err2));
|
|
200
|
+
this.abort(err).catch((err2) => this.errors.raise(err2));
|
|
212
201
|
} else if (err instanceof ConnectivityError) {
|
|
213
202
|
log.info("aborting due to transport ConnectivityError", void 0, {
|
|
214
203
|
F: __dxlog_file,
|
|
@@ -216,22 +205,14 @@ var Connection = class {
|
|
|
216
205
|
S: this,
|
|
217
206
|
C: (f, a) => f(...a)
|
|
218
207
|
});
|
|
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
|
-
});
|
|
208
|
+
this.abort(err).catch((err2) => this.errors.raise(err2));
|
|
229
209
|
}
|
|
230
210
|
if (this._state !== "CLOSED" && this._state !== "CLOSING") {
|
|
231
211
|
await this.connectedTimeoutContext.dispose();
|
|
232
212
|
this.errors.raise(err);
|
|
233
213
|
}
|
|
234
214
|
});
|
|
215
|
+
await this._transport.open();
|
|
235
216
|
for (const signal of this._incomingSignalBuffer) {
|
|
236
217
|
void this._transport.onSignal(signal);
|
|
237
218
|
}
|
|
@@ -598,15 +579,20 @@ var createIceProvider = (iceProviders) => {
|
|
|
598
579
|
}
|
|
599
580
|
cachedIceServers = (await Promise.all(iceProviders.map(({ urls }) => asyncTimeout(fetch(urls, {
|
|
600
581
|
method: "GET"
|
|
601
|
-
}), 1e4).then((response) => response.json()).catch((err) =>
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
582
|
+
}), 1e4).then((response) => response.json()).catch((err) => {
|
|
583
|
+
const isDev = typeof window !== "undefined" && window.location.href.includes("localhost");
|
|
584
|
+
if (!isDev) {
|
|
585
|
+
log2.error("Failed to fetch ICE servers from provider", {
|
|
586
|
+
urls,
|
|
587
|
+
err
|
|
588
|
+
}, {
|
|
589
|
+
F: __dxlog_file2,
|
|
590
|
+
L: 30,
|
|
591
|
+
S: void 0,
|
|
592
|
+
C: (f, a) => f(...a)
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
})))).filter(isNotNullOrUndefined).map(({ iceServers }) => iceServers).flat();
|
|
610
596
|
return cachedIceServers;
|
|
611
597
|
}
|
|
612
598
|
};
|
|
@@ -1197,21 +1183,22 @@ var Peer = class {
|
|
|
1197
1183
|
});
|
|
1198
1184
|
},
|
|
1199
1185
|
onClosed: (err) => {
|
|
1200
|
-
|
|
1186
|
+
const logMeta = {
|
|
1201
1187
|
topic: this.topic,
|
|
1202
1188
|
peerId: this.localInfo,
|
|
1203
1189
|
remoteId: this.remoteInfo,
|
|
1204
1190
|
initiator
|
|
1205
|
-
}
|
|
1191
|
+
};
|
|
1192
|
+
log4("connection closed", logMeta, {
|
|
1206
1193
|
F: __dxlog_file4,
|
|
1207
|
-
L:
|
|
1194
|
+
L: 289,
|
|
1208
1195
|
S: this,
|
|
1209
1196
|
C: (f, a) => f(...a)
|
|
1210
1197
|
});
|
|
1211
1198
|
this._connectionLimiter.doneConnecting(sessionId);
|
|
1212
1199
|
invariant3(this.connection === connection, "Connection mismatch (race condition).", {
|
|
1213
1200
|
F: __dxlog_file4,
|
|
1214
|
-
L:
|
|
1201
|
+
L: 294,
|
|
1215
1202
|
S: this,
|
|
1216
1203
|
A: [
|
|
1217
1204
|
"this.connection === connection",
|
|
@@ -1226,7 +1213,7 @@ var Peer = class {
|
|
|
1226
1213
|
initiator
|
|
1227
1214
|
}, {
|
|
1228
1215
|
F: __dxlog_file4,
|
|
1229
|
-
L:
|
|
1216
|
+
L: 296,
|
|
1230
1217
|
S: this,
|
|
1231
1218
|
C: (f, a) => f(...a)
|
|
1232
1219
|
});
|
|
@@ -1241,6 +1228,12 @@ var Peer = class {
|
|
|
1241
1228
|
}
|
|
1242
1229
|
this._callbacks.onDisconnected();
|
|
1243
1230
|
scheduleTask2(this._connectionCtx, () => {
|
|
1231
|
+
log4("peer became available", logMeta, {
|
|
1232
|
+
F: __dxlog_file4,
|
|
1233
|
+
L: 320,
|
|
1234
|
+
S: this,
|
|
1235
|
+
C: (f, a) => f(...a)
|
|
1236
|
+
});
|
|
1244
1237
|
this.availableToConnect = true;
|
|
1245
1238
|
this._callbacks.onPeerAvailable();
|
|
1246
1239
|
}, this._availableAfter);
|
|
@@ -1261,7 +1254,7 @@ var Peer = class {
|
|
|
1261
1254
|
err
|
|
1262
1255
|
}, {
|
|
1263
1256
|
F: __dxlog_file4,
|
|
1264
|
-
L:
|
|
1257
|
+
L: 338,
|
|
1265
1258
|
S: this,
|
|
1266
1259
|
C: (f, a) => f(...a)
|
|
1267
1260
|
});
|
|
@@ -1274,7 +1267,7 @@ var Peer = class {
|
|
|
1274
1267
|
err
|
|
1275
1268
|
}, {
|
|
1276
1269
|
F: __dxlog_file4,
|
|
1277
|
-
L:
|
|
1270
|
+
L: 345,
|
|
1278
1271
|
S: this,
|
|
1279
1272
|
C: (f, a) => f(...a)
|
|
1280
1273
|
});
|
|
@@ -1293,7 +1286,7 @@ var Peer = class {
|
|
|
1293
1286
|
sessionId: connection.sessionId
|
|
1294
1287
|
}, {
|
|
1295
1288
|
F: __dxlog_file4,
|
|
1296
|
-
L:
|
|
1289
|
+
L: 370,
|
|
1297
1290
|
S: this,
|
|
1298
1291
|
C: (f, a) => f(...a)
|
|
1299
1292
|
});
|
|
@@ -1303,7 +1296,7 @@ var Peer = class {
|
|
|
1303
1296
|
sessionId: connection.sessionId
|
|
1304
1297
|
}, {
|
|
1305
1298
|
F: __dxlog_file4,
|
|
1306
|
-
L:
|
|
1299
|
+
L: 376,
|
|
1307
1300
|
S: this,
|
|
1308
1301
|
C: (f, a) => f(...a)
|
|
1309
1302
|
});
|
|
@@ -1314,7 +1307,7 @@ var Peer = class {
|
|
|
1314
1307
|
message
|
|
1315
1308
|
}, {
|
|
1316
1309
|
F: __dxlog_file4,
|
|
1317
|
-
L:
|
|
1310
|
+
L: 381,
|
|
1318
1311
|
S: this,
|
|
1319
1312
|
C: (f, a) => f(...a)
|
|
1320
1313
|
});
|
|
@@ -1329,7 +1322,7 @@ var Peer = class {
|
|
|
1329
1322
|
topic: this.topic
|
|
1330
1323
|
}, {
|
|
1331
1324
|
F: __dxlog_file4,
|
|
1332
|
-
L:
|
|
1325
|
+
L: 391,
|
|
1333
1326
|
S: this,
|
|
1334
1327
|
C: (f, a) => f(...a)
|
|
1335
1328
|
});
|
|
@@ -1547,10 +1540,16 @@ var Swarm = class {
|
|
|
1547
1540
|
const peer = this._peers.get(swarmEvent.peerLeft.peer);
|
|
1548
1541
|
if (peer) {
|
|
1549
1542
|
peer.advertizing = false;
|
|
1550
|
-
if (peer
|
|
1543
|
+
if (this._isConnectionEstablishmentInProgress(peer)) {
|
|
1544
|
+
log5(`destroying peer, state: ${peer.connection?.state}`, void 0, {
|
|
1545
|
+
F: __dxlog_file5,
|
|
1546
|
+
L: 195,
|
|
1547
|
+
S: this,
|
|
1548
|
+
C: (f, a) => f(...a)
|
|
1549
|
+
});
|
|
1551
1550
|
void this._destroyPeer(swarmEvent.peerLeft.peer, "peer left").catch((err) => log5.catch(err, void 0, {
|
|
1552
1551
|
F: __dxlog_file5,
|
|
1553
|
-
L:
|
|
1552
|
+
L: 196,
|
|
1554
1553
|
S: this,
|
|
1555
1554
|
C: (f, a) => f(...a)
|
|
1556
1555
|
}));
|
|
@@ -1560,7 +1559,7 @@ var Swarm = class {
|
|
|
1560
1559
|
peer: swarmEvent.peerLeft.peer.peerKey
|
|
1561
1560
|
}, {
|
|
1562
1561
|
F: __dxlog_file5,
|
|
1563
|
-
L:
|
|
1562
|
+
L: 199,
|
|
1564
1563
|
S: this,
|
|
1565
1564
|
C: (f, a) => f(...a)
|
|
1566
1565
|
});
|
|
@@ -1573,14 +1572,14 @@ var Swarm = class {
|
|
|
1573
1572
|
message
|
|
1574
1573
|
}, {
|
|
1575
1574
|
F: __dxlog_file5,
|
|
1576
|
-
L:
|
|
1575
|
+
L: 208,
|
|
1577
1576
|
S: this,
|
|
1578
1577
|
C: (f, a) => f(...a)
|
|
1579
1578
|
});
|
|
1580
1579
|
if (this._ctx.disposed) {
|
|
1581
1580
|
log5("ignored for disposed swarm", void 0, {
|
|
1582
1581
|
F: __dxlog_file5,
|
|
1583
|
-
L:
|
|
1582
|
+
L: 210,
|
|
1584
1583
|
S: this,
|
|
1585
1584
|
C: (f, a) => f(...a)
|
|
1586
1585
|
});
|
|
@@ -1590,7 +1589,7 @@ var Swarm = class {
|
|
|
1590
1589
|
}
|
|
1591
1590
|
invariant4(message.author, void 0, {
|
|
1592
1591
|
F: __dxlog_file5,
|
|
1593
|
-
L:
|
|
1592
|
+
L: 215,
|
|
1594
1593
|
S: this,
|
|
1595
1594
|
A: [
|
|
1596
1595
|
"message.author",
|
|
@@ -1602,7 +1601,7 @@ var Swarm = class {
|
|
|
1602
1601
|
message
|
|
1603
1602
|
}, {
|
|
1604
1603
|
F: __dxlog_file5,
|
|
1605
|
-
L:
|
|
1604
|
+
L: 217,
|
|
1606
1605
|
S: this,
|
|
1607
1606
|
C: (f, a) => f(...a)
|
|
1608
1607
|
});
|
|
@@ -1615,7 +1614,7 @@ var Swarm = class {
|
|
|
1615
1614
|
message
|
|
1616
1615
|
}, {
|
|
1617
1616
|
F: __dxlog_file5,
|
|
1618
|
-
L:
|
|
1617
|
+
L: 221,
|
|
1619
1618
|
S: this,
|
|
1620
1619
|
C: (f, a) => f(...a)
|
|
1621
1620
|
});
|
|
@@ -1633,14 +1632,14 @@ var Swarm = class {
|
|
|
1633
1632
|
message
|
|
1634
1633
|
}, {
|
|
1635
1634
|
F: __dxlog_file5,
|
|
1636
|
-
L:
|
|
1635
|
+
L: 232,
|
|
1637
1636
|
S: this,
|
|
1638
1637
|
C: (f, a) => f(...a)
|
|
1639
1638
|
});
|
|
1640
1639
|
if (this._ctx.disposed) {
|
|
1641
1640
|
log5.info("ignored for offline swarm", void 0, {
|
|
1642
1641
|
F: __dxlog_file5,
|
|
1643
|
-
L:
|
|
1642
|
+
L: 234,
|
|
1644
1643
|
S: this,
|
|
1645
1644
|
C: (f, a) => f(...a)
|
|
1646
1645
|
});
|
|
@@ -1648,7 +1647,7 @@ var Swarm = class {
|
|
|
1648
1647
|
}
|
|
1649
1648
|
invariant4(message.recipient.peerKey === this._ownPeer.peerKey, `Invalid signal peer id expected=${this.ownPeerId}, actual=${message.recipient}`, {
|
|
1650
1649
|
F: __dxlog_file5,
|
|
1651
|
-
L:
|
|
1650
|
+
L: 237,
|
|
1652
1651
|
S: this,
|
|
1653
1652
|
A: [
|
|
1654
1653
|
"message.recipient.peerKey === this._ownPeer.peerKey",
|
|
@@ -1657,7 +1656,7 @@ var Swarm = class {
|
|
|
1657
1656
|
});
|
|
1658
1657
|
invariant4(message.topic?.equals(this._topic), void 0, {
|
|
1659
1658
|
F: __dxlog_file5,
|
|
1660
|
-
L:
|
|
1659
|
+
L: 241,
|
|
1661
1660
|
S: this,
|
|
1662
1661
|
A: [
|
|
1663
1662
|
"message.topic?.equals(this._topic)",
|
|
@@ -1666,7 +1665,7 @@ var Swarm = class {
|
|
|
1666
1665
|
});
|
|
1667
1666
|
invariant4(message.author, void 0, {
|
|
1668
1667
|
F: __dxlog_file5,
|
|
1669
|
-
L:
|
|
1668
|
+
L: 242,
|
|
1670
1669
|
S: this,
|
|
1671
1670
|
A: [
|
|
1672
1671
|
"message.author",
|
|
@@ -1687,13 +1686,13 @@ var Swarm = class {
|
|
|
1687
1686
|
async goOnline() {
|
|
1688
1687
|
this._ctx = new Context4(void 0, {
|
|
1689
1688
|
F: __dxlog_file5,
|
|
1690
|
-
L:
|
|
1689
|
+
L: 258
|
|
1691
1690
|
});
|
|
1692
1691
|
}
|
|
1693
1692
|
_getOrCreatePeer(peerInfo) {
|
|
1694
1693
|
invariant4(peerInfo.peerKey, "PeerInfo.peerKey is required", {
|
|
1695
1694
|
F: __dxlog_file5,
|
|
1696
|
-
L:
|
|
1695
|
+
L: 262,
|
|
1697
1696
|
S: this,
|
|
1698
1697
|
A: [
|
|
1699
1698
|
"peerInfo.peerKey",
|
|
@@ -1711,6 +1710,12 @@ var Swarm = class {
|
|
|
1711
1710
|
},
|
|
1712
1711
|
onDisconnected: async () => {
|
|
1713
1712
|
if (this._isUnregistered(peer)) {
|
|
1713
|
+
log5.verbose("ignored onDisconnected for unregistered peer", void 0, {
|
|
1714
|
+
F: __dxlog_file5,
|
|
1715
|
+
L: 282,
|
|
1716
|
+
S: this,
|
|
1717
|
+
C: (f, a) => f(...a)
|
|
1718
|
+
});
|
|
1714
1719
|
return;
|
|
1715
1720
|
}
|
|
1716
1721
|
if (!peer.advertizing) {
|
|
@@ -1725,7 +1730,7 @@ var Swarm = class {
|
|
|
1725
1730
|
peerInfo
|
|
1726
1731
|
}, {
|
|
1727
1732
|
F: __dxlog_file5,
|
|
1728
|
-
L:
|
|
1733
|
+
L: 296,
|
|
1729
1734
|
S: this,
|
|
1730
1735
|
C: (f, a) => f(...a)
|
|
1731
1736
|
});
|
|
@@ -1747,10 +1752,19 @@ var Swarm = class {
|
|
|
1747
1752
|
return peer;
|
|
1748
1753
|
}
|
|
1749
1754
|
async _destroyPeer(peerInfo, reason) {
|
|
1755
|
+
log5("destroy peer", {
|
|
1756
|
+
peerKey: peerInfo.peerKey,
|
|
1757
|
+
reason
|
|
1758
|
+
}, {
|
|
1759
|
+
F: __dxlog_file5,
|
|
1760
|
+
L: 318,
|
|
1761
|
+
S: this,
|
|
1762
|
+
C: (f, a) => f(...a)
|
|
1763
|
+
});
|
|
1750
1764
|
const peer = this._peers.get(peerInfo);
|
|
1751
1765
|
invariant4(peer, void 0, {
|
|
1752
1766
|
F: __dxlog_file5,
|
|
1753
|
-
L:
|
|
1767
|
+
L: 320,
|
|
1754
1768
|
S: this,
|
|
1755
1769
|
A: [
|
|
1756
1770
|
"peer",
|
|
@@ -1780,7 +1794,7 @@ var Swarm = class {
|
|
|
1780
1794
|
} catch (err) {
|
|
1781
1795
|
log5("initiation error", err, {
|
|
1782
1796
|
F: __dxlog_file5,
|
|
1783
|
-
L:
|
|
1797
|
+
L: 347,
|
|
1784
1798
|
S: this,
|
|
1785
1799
|
C: (f, a) => f(...a)
|
|
1786
1800
|
});
|
|
@@ -1811,7 +1825,7 @@ var Swarm = class {
|
|
|
1811
1825
|
remotePeer
|
|
1812
1826
|
}, {
|
|
1813
1827
|
F: __dxlog_file5,
|
|
1814
|
-
L:
|
|
1828
|
+
L: 375,
|
|
1815
1829
|
S: this,
|
|
1816
1830
|
C: (f, a) => f(...a)
|
|
1817
1831
|
});
|
|
@@ -1830,7 +1844,7 @@ var Swarm = class {
|
|
|
1830
1844
|
remotePeer
|
|
1831
1845
|
}, {
|
|
1832
1846
|
F: __dxlog_file5,
|
|
1833
|
-
L:
|
|
1847
|
+
L: 391,
|
|
1834
1848
|
S: this,
|
|
1835
1849
|
C: (f, a) => f(...a)
|
|
1836
1850
|
});
|
|
@@ -1840,7 +1854,7 @@ var Swarm = class {
|
|
|
1840
1854
|
remotePeer
|
|
1841
1855
|
}, {
|
|
1842
1856
|
F: __dxlog_file5,
|
|
1843
|
-
L:
|
|
1857
|
+
L: 394,
|
|
1844
1858
|
S: this,
|
|
1845
1859
|
C: (f, a) => f(...a)
|
|
1846
1860
|
});
|
|
@@ -1852,6 +1866,16 @@ var Swarm = class {
|
|
|
1852
1866
|
}
|
|
1853
1867
|
await peer.closeConnection();
|
|
1854
1868
|
}
|
|
1869
|
+
_isConnectionEstablishmentInProgress(peer) {
|
|
1870
|
+
if (!peer.connection) {
|
|
1871
|
+
return true;
|
|
1872
|
+
}
|
|
1873
|
+
return [
|
|
1874
|
+
ConnectionState.INITIAL,
|
|
1875
|
+
ConnectionState.CREATED,
|
|
1876
|
+
ConnectionState.CONNECTING
|
|
1877
|
+
].includes(peer.connection.state);
|
|
1878
|
+
}
|
|
1855
1879
|
_isUnregistered(peer) {
|
|
1856
1880
|
return !peer || this._peers.get(peer.remoteInfo) !== peer;
|
|
1857
1881
|
}
|
|
@@ -2226,52 +2250,37 @@ var SwarmNetworkManager = class {
|
|
|
2226
2250
|
/**
|
|
2227
2251
|
* Join the swarm.
|
|
2228
2252
|
*/
|
|
2229
|
-
async joinSwarm({ topic,
|
|
2253
|
+
async joinSwarm({ topic, topology, protocolProvider: protocol, label }) {
|
|
2230
2254
|
invariant6(PublicKey8.isPublicKey(topic), void 0, {
|
|
2231
2255
|
F: __dxlog_file8,
|
|
2232
|
-
L:
|
|
2256
|
+
L: 160,
|
|
2233
2257
|
S: this,
|
|
2234
2258
|
A: [
|
|
2235
2259
|
"PublicKey.isPublicKey(topic)",
|
|
2236
2260
|
""
|
|
2237
2261
|
]
|
|
2238
2262
|
});
|
|
2239
|
-
|
|
2240
|
-
peerInfo = {
|
|
2241
|
-
peerKey: this._peerInfo?.peerKey ?? PublicKey8.random().toHex(),
|
|
2242
|
-
identityKey: this._peerInfo?.identityKey ?? PublicKey8.random().toHex()
|
|
2243
|
-
};
|
|
2244
|
-
}
|
|
2245
|
-
invariant6(PublicKey8.from(peerInfo.peerKey), void 0, {
|
|
2246
|
-
F: __dxlog_file8,
|
|
2247
|
-
L: 168,
|
|
2248
|
-
S: this,
|
|
2249
|
-
A: [
|
|
2250
|
-
"PublicKey.from(peerInfo.peerKey)",
|
|
2251
|
-
""
|
|
2252
|
-
]
|
|
2253
|
-
});
|
|
2254
|
-
invariant6(PublicKey8.from(peerInfo.identityKey), void 0, {
|
|
2263
|
+
invariant6(topology, void 0, {
|
|
2255
2264
|
F: __dxlog_file8,
|
|
2256
|
-
L:
|
|
2265
|
+
L: 161,
|
|
2257
2266
|
S: this,
|
|
2258
2267
|
A: [
|
|
2259
|
-
"
|
|
2268
|
+
"topology",
|
|
2260
2269
|
""
|
|
2261
2270
|
]
|
|
2262
2271
|
});
|
|
2263
|
-
invariant6(
|
|
2272
|
+
invariant6(this._peerInfo, void 0, {
|
|
2264
2273
|
F: __dxlog_file8,
|
|
2265
|
-
L:
|
|
2274
|
+
L: 162,
|
|
2266
2275
|
S: this,
|
|
2267
2276
|
A: [
|
|
2268
|
-
"
|
|
2277
|
+
"this._peerInfo",
|
|
2269
2278
|
""
|
|
2270
2279
|
]
|
|
2271
2280
|
});
|
|
2272
2281
|
invariant6(typeof protocol === "function", void 0, {
|
|
2273
2282
|
F: __dxlog_file8,
|
|
2274
|
-
L:
|
|
2283
|
+
L: 163,
|
|
2275
2284
|
S: this,
|
|
2276
2285
|
A: [
|
|
2277
2286
|
"typeof protocol === 'function'",
|
|
@@ -2283,21 +2292,21 @@ var SwarmNetworkManager = class {
|
|
|
2283
2292
|
}
|
|
2284
2293
|
log8("joining", {
|
|
2285
2294
|
topic: PublicKey8.from(topic),
|
|
2286
|
-
peerInfo,
|
|
2295
|
+
peerInfo: this._peerInfo,
|
|
2287
2296
|
topology: topology.toString()
|
|
2288
2297
|
}, {
|
|
2289
2298
|
F: __dxlog_file8,
|
|
2290
|
-
L:
|
|
2299
|
+
L: 168,
|
|
2291
2300
|
S: this,
|
|
2292
2301
|
C: (f, a) => f(...a)
|
|
2293
2302
|
});
|
|
2294
|
-
const swarm = new Swarm(topic,
|
|
2303
|
+
const swarm = new Swarm(topic, this._peerInfo, topology, protocol, this._messenger, this._transportFactory, label, this._connectionLimiter);
|
|
2295
2304
|
swarm.errors.handle((error) => {
|
|
2296
2305
|
log8("swarm error", {
|
|
2297
2306
|
error
|
|
2298
2307
|
}, {
|
|
2299
2308
|
F: __dxlog_file8,
|
|
2300
|
-
L:
|
|
2309
|
+
L: 181,
|
|
2301
2310
|
S: this,
|
|
2302
2311
|
C: (f, a) => f(...a)
|
|
2303
2312
|
});
|
|
@@ -2307,10 +2316,10 @@ var SwarmNetworkManager = class {
|
|
|
2307
2316
|
await swarm.open();
|
|
2308
2317
|
this._signalConnection.join({
|
|
2309
2318
|
topic,
|
|
2310
|
-
peer:
|
|
2319
|
+
peer: this._peerInfo
|
|
2311
2320
|
}).catch((error) => log8.catch(error, void 0, {
|
|
2312
2321
|
F: __dxlog_file8,
|
|
2313
|
-
L:
|
|
2322
|
+
L: 190,
|
|
2314
2323
|
S: this,
|
|
2315
2324
|
C: (f, a) => f(...a)
|
|
2316
2325
|
}));
|
|
@@ -2321,7 +2330,7 @@ var SwarmNetworkManager = class {
|
|
|
2321
2330
|
count: this._swarms.size
|
|
2322
2331
|
}, {
|
|
2323
2332
|
F: __dxlog_file8,
|
|
2324
|
-
L:
|
|
2333
|
+
L: 194,
|
|
2325
2334
|
S: this,
|
|
2326
2335
|
C: (f, a) => f(...a)
|
|
2327
2336
|
});
|
|
@@ -2340,7 +2349,7 @@ var SwarmNetworkManager = class {
|
|
|
2340
2349
|
topic: PublicKey8.from(topic)
|
|
2341
2350
|
}, {
|
|
2342
2351
|
F: __dxlog_file8,
|
|
2343
|
-
L:
|
|
2352
|
+
L: 211,
|
|
2344
2353
|
S: this,
|
|
2345
2354
|
C: (f, a) => f(...a)
|
|
2346
2355
|
});
|
|
@@ -2361,7 +2370,7 @@ var SwarmNetworkManager = class {
|
|
|
2361
2370
|
count: this._swarms.size
|
|
2362
2371
|
}, {
|
|
2363
2372
|
F: __dxlog_file8,
|
|
2364
|
-
L:
|
|
2373
|
+
L: 225,
|
|
2365
2374
|
S: this,
|
|
2366
2375
|
C: (f, a) => f(...a)
|
|
2367
2376
|
});
|
|
@@ -2630,7 +2639,7 @@ var sortByXorDistance = (keys, reference) => {
|
|
|
2630
2639
|
};
|
|
2631
2640
|
var distXor = (a, b) => {
|
|
2632
2641
|
const maxLength = Math.max(a.length, b.length);
|
|
2633
|
-
const result =
|
|
2642
|
+
const result = Buffer.allocUnsafe(maxLength);
|
|
2634
2643
|
for (let i = 0; i < maxLength; i++) {
|
|
2635
2644
|
result[i] = (a[i] || 0) ^ (b[i] || 0);
|
|
2636
2645
|
}
|
|
@@ -2865,11 +2874,12 @@ var MemoryTransport = class _MemoryTransport {
|
|
|
2865
2874
|
this.errors.raise(err);
|
|
2866
2875
|
});
|
|
2867
2876
|
}
|
|
2877
|
+
return this;
|
|
2868
2878
|
}
|
|
2869
2879
|
async close() {
|
|
2870
2880
|
log11("closing...", void 0, {
|
|
2871
2881
|
F: __dxlog_file12,
|
|
2872
|
-
L:
|
|
2882
|
+
L: 130,
|
|
2873
2883
|
S: this,
|
|
2874
2884
|
C: (f, a) => f(...a)
|
|
2875
2885
|
});
|
|
@@ -2890,17 +2900,18 @@ var MemoryTransport = class _MemoryTransport {
|
|
|
2890
2900
|
this.closed.emit();
|
|
2891
2901
|
log11("closed", void 0, {
|
|
2892
2902
|
F: __dxlog_file12,
|
|
2893
|
-
L:
|
|
2903
|
+
L: 158,
|
|
2894
2904
|
S: this,
|
|
2895
2905
|
C: (f, a) => f(...a)
|
|
2896
2906
|
});
|
|
2907
|
+
return this;
|
|
2897
2908
|
}
|
|
2898
2909
|
async onSignal({ payload }) {
|
|
2899
2910
|
log11("received signal", {
|
|
2900
2911
|
payload
|
|
2901
2912
|
}, {
|
|
2902
2913
|
F: __dxlog_file12,
|
|
2903
|
-
L:
|
|
2914
|
+
L: 163,
|
|
2904
2915
|
S: this,
|
|
2905
2916
|
C: (f, a) => f(...a)
|
|
2906
2917
|
});
|
|
@@ -2936,524 +2947,980 @@ var toError = (err) => err instanceof Error ? err : new Error(String(err));
|
|
|
2936
2947
|
// packages/core/mesh/network-manager/src/transport/transport.ts
|
|
2937
2948
|
var TransportKind;
|
|
2938
2949
|
(function(TransportKind2) {
|
|
2939
|
-
TransportKind2["
|
|
2940
|
-
TransportKind2["
|
|
2941
|
-
TransportKind2["LIBDATACHANNEL"] = "LIBDATACHANNEL";
|
|
2950
|
+
TransportKind2["WEB_RTC"] = "WEB-RTC";
|
|
2951
|
+
TransportKind2["WEB_RTC_PROXY"] = "WEB-RTC_PROXY";
|
|
2942
2952
|
TransportKind2["MEMORY"] = "MEMORY";
|
|
2943
2953
|
TransportKind2["TCP"] = "TCP";
|
|
2944
2954
|
})(TransportKind || (TransportKind = {}));
|
|
2945
2955
|
|
|
2946
|
-
// packages/core/mesh/network-manager/src/transport/
|
|
2947
|
-
import
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2956
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-connection-factory.ts
|
|
2957
|
+
import { Mutex } from "@dxos/async";
|
|
2958
|
+
var BrowserRtcConnectionFactory = class {
|
|
2959
|
+
async initialize() {
|
|
2960
|
+
}
|
|
2961
|
+
async onConnectionDestroyed() {
|
|
2962
|
+
}
|
|
2963
|
+
async createConnection(config) {
|
|
2964
|
+
return new RTCPeerConnection(config);
|
|
2965
|
+
}
|
|
2966
|
+
async initConnection(connection, info) {
|
|
2967
|
+
}
|
|
2968
|
+
};
|
|
2969
|
+
var NodeRtcConnectionFactory = class _NodeRtcConnectionFactory {
|
|
2970
|
+
static {
|
|
2971
|
+
this._createdConnections = 0;
|
|
2972
|
+
}
|
|
2973
|
+
static {
|
|
2974
|
+
this._cleanupMutex = new Mutex();
|
|
2975
|
+
}
|
|
2976
|
+
// This should be inside the function to avoid triggering `eval` in the global scope.
|
|
2977
|
+
// eslint-disable-next-line no-new-func
|
|
2978
|
+
// TODO(burdon): Do imports here?
|
|
2979
|
+
async initialize() {
|
|
2980
|
+
}
|
|
2981
|
+
async onConnectionDestroyed() {
|
|
2982
|
+
return _NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
|
|
2983
|
+
if (--_NodeRtcConnectionFactory._createdConnections === 0) {
|
|
2984
|
+
(await import("#node-datachannel")).cleanup();
|
|
2985
|
+
}
|
|
2986
|
+
});
|
|
2987
|
+
}
|
|
2988
|
+
async createConnection(config) {
|
|
2989
|
+
return _NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
|
|
2990
|
+
const { RTCPeerConnection: RTCPeerConnection1 } = await import("#node-datachannel/polyfill");
|
|
2991
|
+
_NodeRtcConnectionFactory._createdConnections++;
|
|
2992
|
+
return new RTCPeerConnection1(config);
|
|
2993
|
+
});
|
|
2994
|
+
}
|
|
2995
|
+
async initConnection(connection, info) {
|
|
2996
|
+
if (info.initiator) {
|
|
2997
|
+
connection.onnegotiationneeded?.(null);
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
3000
|
+
};
|
|
3001
|
+
var getRtcConnectionFactory = () => {
|
|
3002
|
+
return typeof globalThis.RTCPeerConnection === "undefined" ? new NodeRtcConnectionFactory() : new BrowserRtcConnectionFactory();
|
|
3003
|
+
};
|
|
2954
3004
|
|
|
2955
|
-
// packages/core/mesh/network-manager/src/transport/webrtc.ts
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
}
|
|
2960
|
-
}
|
|
3005
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-peer-connection.ts
|
|
3006
|
+
import { synchronized as synchronized5, Trigger as Trigger3, Mutex as Mutex2 } from "@dxos/async";
|
|
3007
|
+
import { invariant as invariant12 } from "@dxos/invariant";
|
|
3008
|
+
import { log as log13, logInfo as logInfo4 } from "@dxos/log";
|
|
3009
|
+
import { ConnectivityError as ConnectivityError3 } from "@dxos/protocols";
|
|
3010
|
+
import { trace as trace4 } from "@dxos/tracing";
|
|
2961
3011
|
|
|
2962
|
-
// packages/core/mesh/network-manager/src/transport/
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
}
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
var SimplePeerTransport = class {
|
|
2978
|
-
get isOpen() {
|
|
2979
|
-
return this._piped && !this._closed;
|
|
3012
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-channel.ts
|
|
3013
|
+
import { Duplex } from "@dxos/node-std/stream";
|
|
3014
|
+
import { Event as AsyncEvent } from "@dxos/async";
|
|
3015
|
+
import { Resource } from "@dxos/context";
|
|
3016
|
+
import { ErrorStream as ErrorStream4 } from "@dxos/debug";
|
|
3017
|
+
import { invariant as invariant11 } from "@dxos/invariant";
|
|
3018
|
+
import { log as log12 } from "@dxos/log";
|
|
3019
|
+
import { ConnectivityError as ConnectivityError2 } from "@dxos/protocols";
|
|
3020
|
+
|
|
3021
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-stats.ts
|
|
3022
|
+
var describeSelectedRemoteCandidate = async (connection) => {
|
|
3023
|
+
const stats = connection && await getRtcConnectionStats(connection);
|
|
3024
|
+
const rc = stats?.remoteCandidate;
|
|
3025
|
+
if (!rc) {
|
|
3026
|
+
return "unavailable";
|
|
2980
3027
|
}
|
|
2981
|
-
|
|
2982
|
-
|
|
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();
|
|
3028
|
+
if (rc.candidateType === "relay") {
|
|
3029
|
+
return `${rc.ip}:${rc.port} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
|
|
2993
3030
|
}
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
bytesReceived: 0,
|
|
3000
|
-
packetsSent: 0,
|
|
3001
|
-
packetsReceived: 0,
|
|
3002
|
-
rawStats: {}
|
|
3003
|
-
};
|
|
3004
|
-
}
|
|
3031
|
+
return `${rc.ip}:${rc.port} ${rc.candidateType}`;
|
|
3032
|
+
};
|
|
3033
|
+
var createRtcTransportStats = async (connection, topic) => {
|
|
3034
|
+
const stats = connection && await getRtcConnectionStats(connection, topic);
|
|
3035
|
+
if (!stats) {
|
|
3005
3036
|
return {
|
|
3006
|
-
bytesSent:
|
|
3007
|
-
bytesReceived:
|
|
3008
|
-
packetsSent:
|
|
3009
|
-
packetsReceived:
|
|
3010
|
-
rawStats:
|
|
3037
|
+
bytesSent: 0,
|
|
3038
|
+
bytesReceived: 0,
|
|
3039
|
+
packetsSent: 0,
|
|
3040
|
+
packetsReceived: 0,
|
|
3041
|
+
rawStats: {}
|
|
3011
3042
|
};
|
|
3012
3043
|
}
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3044
|
+
return {
|
|
3045
|
+
bytesSent: stats.dataChannel?.bytesSent,
|
|
3046
|
+
bytesReceived: stats.dataChannel?.bytesReceived,
|
|
3047
|
+
packetsSent: 0,
|
|
3048
|
+
packetsReceived: 0,
|
|
3049
|
+
rawStats: stats.raw
|
|
3050
|
+
};
|
|
3051
|
+
};
|
|
3052
|
+
var getRtcConnectionStats = async (connection, channelTopic) => {
|
|
3053
|
+
const stats = await connection.getStats();
|
|
3054
|
+
const statsEntries = Array.from(stats.entries());
|
|
3055
|
+
const transport = statsEntries.find(([_, entry]) => entry.type === "transport")?.[1];
|
|
3056
|
+
const selectedCandidatePair = transport && statsEntries.find(([entryId]) => entryId === transport.selectedCandidatePairId)?.[1];
|
|
3057
|
+
const remoteCandidate = selectedCandidatePair && statsEntries.find(([entryId]) => entryId === selectedCandidatePair.remoteCandidateId)?.[1];
|
|
3058
|
+
const dataChannel = channelTopic && statsEntries.find(([_, entry]) => entry.type === "data-channel" && entry.label === channelTopic)?.[1];
|
|
3059
|
+
return {
|
|
3060
|
+
transport,
|
|
3061
|
+
selectedCandidatePair,
|
|
3062
|
+
dataChannel,
|
|
3063
|
+
remoteCandidate,
|
|
3064
|
+
raw: Object.fromEntries(stats)
|
|
3065
|
+
};
|
|
3066
|
+
};
|
|
3067
|
+
|
|
3068
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-channel.ts
|
|
3069
|
+
var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-channel.ts";
|
|
3070
|
+
var MAX_MESSAGE_SIZE = 64 * 1024;
|
|
3071
|
+
var MAX_BUFFERED_AMOUNT = 64 * 1024;
|
|
3072
|
+
var RtcTransportChannel = class extends Resource {
|
|
3073
|
+
constructor(_connection, _options) {
|
|
3074
|
+
super();
|
|
3075
|
+
this._connection = _connection;
|
|
3076
|
+
this._options = _options;
|
|
3077
|
+
this.closed = new AsyncEvent();
|
|
3078
|
+
this.connected = new AsyncEvent();
|
|
3079
|
+
this.errors = new ErrorStream4();
|
|
3080
|
+
this._streamDataFlushedCallback = null;
|
|
3081
|
+
this._isChannelCreationInProgress = false;
|
|
3035
3082
|
}
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
if (rc.candidateType === "relay") {
|
|
3043
|
-
return `${rc.ip}:${rc.port}/${rc.protocol} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
|
|
3083
|
+
get isRtcChannelCreationInProgress() {
|
|
3084
|
+
return this._isChannelCreationInProgress;
|
|
3085
|
+
}
|
|
3086
|
+
onConnectionError(error) {
|
|
3087
|
+
if (this.isOpen) {
|
|
3088
|
+
this.errors.raise(error);
|
|
3044
3089
|
}
|
|
3045
|
-
return `${rc.ip}:${rc.port}/${rc.protocol} ${rc.candidateType}`;
|
|
3046
3090
|
}
|
|
3047
|
-
async
|
|
3048
|
-
|
|
3049
|
-
id: this._instanceId
|
|
3050
|
-
}), {
|
|
3091
|
+
async _open() {
|
|
3092
|
+
invariant11(!this._isChannelCreationInProgress, void 0, {
|
|
3051
3093
|
F: __dxlog_file13,
|
|
3052
|
-
L:
|
|
3094
|
+
L: 56,
|
|
3053
3095
|
S: this,
|
|
3054
|
-
|
|
3096
|
+
A: [
|
|
3097
|
+
"!this._isChannelCreationInProgress",
|
|
3098
|
+
""
|
|
3099
|
+
]
|
|
3055
3100
|
});
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3101
|
+
this._isChannelCreationInProgress = true;
|
|
3102
|
+
this._connection.createDataChannel(this._options.topic).then((channel) => {
|
|
3103
|
+
if (this.isOpen) {
|
|
3104
|
+
this._channel = channel;
|
|
3105
|
+
this._initChannel(this._channel);
|
|
3106
|
+
} else {
|
|
3107
|
+
this._safeCloseChannel(channel);
|
|
3108
|
+
}
|
|
3109
|
+
}).catch((err) => {
|
|
3110
|
+
if (this.isOpen) {
|
|
3111
|
+
this.errors.raise(new ConnectivityError2(`Failed to create a channel: ${err?.message ?? "unknown reason."}`));
|
|
3112
|
+
}
|
|
3113
|
+
}).finally(() => {
|
|
3114
|
+
this._isChannelCreationInProgress = false;
|
|
3115
|
+
});
|
|
3116
|
+
}
|
|
3117
|
+
async _close() {
|
|
3118
|
+
if (this._channel) {
|
|
3119
|
+
this._safeCloseChannel(this._channel);
|
|
3120
|
+
this._channel = void 0;
|
|
3121
|
+
this._stream = void 0;
|
|
3122
|
+
}
|
|
3123
|
+
this.closed.emit();
|
|
3124
|
+
log12("closed", void 0, {
|
|
3059
3125
|
F: __dxlog_file13,
|
|
3060
|
-
L:
|
|
3126
|
+
L: 86,
|
|
3061
3127
|
S: this,
|
|
3062
3128
|
C: (f, a) => f(...a)
|
|
3063
3129
|
});
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
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
|
|
3130
|
+
}
|
|
3131
|
+
_initChannel(channel) {
|
|
3132
|
+
Object.assign(channel, {
|
|
3133
|
+
onopen: () => {
|
|
3134
|
+
if (!this.isOpen) {
|
|
3135
|
+
log12.warn("channel opened in a closed transport", {
|
|
3136
|
+
topic: this._options.topic
|
|
3118
3137
|
}, {
|
|
3119
3138
|
F: __dxlog_file13,
|
|
3120
|
-
L:
|
|
3139
|
+
L: 93,
|
|
3121
3140
|
S: this,
|
|
3122
3141
|
C: (f, a) => f(...a)
|
|
3123
3142
|
});
|
|
3124
|
-
this.
|
|
3143
|
+
this._safeCloseChannel(channel);
|
|
3144
|
+
return;
|
|
3125
3145
|
}
|
|
3126
|
-
|
|
3127
|
-
log12.info("simple-peer error", err, {
|
|
3146
|
+
log12("onopen", void 0, {
|
|
3128
3147
|
F: __dxlog_file13,
|
|
3129
|
-
L:
|
|
3148
|
+
L: 98,
|
|
3130
3149
|
S: this,
|
|
3131
3150
|
C: (f, a) => f(...a)
|
|
3132
3151
|
});
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
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, {
|
|
3152
|
+
const duplex = new Duplex({
|
|
3153
|
+
read: () => {
|
|
3154
|
+
},
|
|
3155
|
+
write: (chunk, encoding, callback) => {
|
|
3156
|
+
return this._handleChannelWrite(chunk, callback);
|
|
3157
|
+
}
|
|
3158
|
+
});
|
|
3159
|
+
duplex.pipe(this._options.stream).pipe(duplex);
|
|
3160
|
+
this._stream = duplex;
|
|
3161
|
+
this.connected.emit();
|
|
3162
|
+
},
|
|
3163
|
+
onclose: async () => {
|
|
3164
|
+
log12("onclose", void 0, {
|
|
3159
3165
|
F: __dxlog_file13,
|
|
3160
|
-
L:
|
|
3166
|
+
L: 111,
|
|
3161
3167
|
S: this,
|
|
3162
3168
|
C: (f, a) => f(...a)
|
|
3163
3169
|
});
|
|
3164
|
-
this.
|
|
3165
|
-
}
|
|
3166
|
-
|
|
3167
|
-
if (
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
F: __dxlog_file13,
|
|
3174
|
-
L: 204,
|
|
3175
|
-
S: this,
|
|
3176
|
-
C: (f, a) => f(...a)
|
|
3177
|
-
});
|
|
3170
|
+
await this.close();
|
|
3171
|
+
},
|
|
3172
|
+
onmessage: (event) => {
|
|
3173
|
+
if (!this._stream) {
|
|
3174
|
+
log12.warn("ignoring message on a closed channel", void 0, {
|
|
3175
|
+
F: __dxlog_file13,
|
|
3176
|
+
L: 117,
|
|
3177
|
+
S: this,
|
|
3178
|
+
C: (f, a) => f(...a)
|
|
3178
3179
|
});
|
|
3180
|
+
return;
|
|
3179
3181
|
}
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3182
|
+
let data = event.data;
|
|
3183
|
+
if (data instanceof ArrayBuffer) {
|
|
3184
|
+
data = Buffer.from(data);
|
|
3185
|
+
}
|
|
3186
|
+
this._stream.push(data);
|
|
3187
|
+
},
|
|
3188
|
+
onerror: (event) => {
|
|
3189
|
+
if (this.isOpen) {
|
|
3190
|
+
const err = event.error instanceof Error ? event.error : new Error(`Datachannel error: ${event.type}.`);
|
|
3191
|
+
this.errors.raise(err);
|
|
3192
|
+
}
|
|
3193
|
+
},
|
|
3194
|
+
onbufferedamountlow: () => {
|
|
3195
|
+
const cb = this._streamDataFlushedCallback;
|
|
3196
|
+
this._streamDataFlushedCallback = null;
|
|
3197
|
+
cb?.();
|
|
3187
3198
|
}
|
|
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
3199
|
});
|
|
3198
3200
|
}
|
|
3199
|
-
async
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3201
|
+
async _handleChannelWrite(chunk, callback) {
|
|
3202
|
+
if (!this._channel) {
|
|
3203
|
+
log12.warn("writing to a channel after a connection was closed", void 0, {
|
|
3204
|
+
F: __dxlog_file13,
|
|
3205
|
+
L: 145,
|
|
3206
|
+
S: this,
|
|
3207
|
+
C: (f, a) => f(...a)
|
|
3208
|
+
});
|
|
3207
3209
|
return;
|
|
3208
3210
|
}
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
log12("closed", void 0, {
|
|
3214
|
-
F: __dxlog_file13,
|
|
3215
|
-
L: 230,
|
|
3216
|
-
S: this,
|
|
3217
|
-
C: (f, a) => f(...a)
|
|
3218
|
-
});
|
|
3219
|
-
}
|
|
3220
|
-
async onSignal(signal) {
|
|
3221
|
-
if (this._closed) {
|
|
3211
|
+
if (chunk.length > MAX_MESSAGE_SIZE) {
|
|
3212
|
+
const error = new Error(`Message too large: ${chunk.length} > ${MAX_MESSAGE_SIZE}.`);
|
|
3213
|
+
this.errors.raise(error);
|
|
3214
|
+
callback();
|
|
3222
3215
|
return;
|
|
3223
3216
|
}
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3217
|
+
try {
|
|
3218
|
+
this._channel.send(chunk);
|
|
3219
|
+
} catch (err) {
|
|
3220
|
+
this.errors.raise(err);
|
|
3221
|
+
callback();
|
|
3222
|
+
return;
|
|
3223
|
+
}
|
|
3224
|
+
if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {
|
|
3225
|
+
if (this._streamDataFlushedCallback !== null) {
|
|
3226
|
+
log12.error("consumer trying to write before we are ready for more data", void 0, {
|
|
3227
|
+
F: __dxlog_file13,
|
|
3228
|
+
L: 166,
|
|
3229
|
+
S: this,
|
|
3230
|
+
C: (f, a) => f(...a)
|
|
3231
|
+
});
|
|
3232
|
+
}
|
|
3233
|
+
this._streamDataFlushedCallback = callback;
|
|
3234
|
+
} else {
|
|
3235
|
+
callback();
|
|
3231
3236
|
}
|
|
3232
3237
|
}
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3238
|
+
_safeCloseChannel(channel) {
|
|
3239
|
+
try {
|
|
3240
|
+
channel.close();
|
|
3241
|
+
} catch (error) {
|
|
3242
|
+
log12.catch(error, void 0, {
|
|
3243
|
+
F: __dxlog_file13,
|
|
3244
|
+
L: 178,
|
|
3245
|
+
S: this,
|
|
3246
|
+
C: (f, a) => f(...a)
|
|
3247
|
+
});
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
onSignal(signal) {
|
|
3251
|
+
return this._connection.onSignal(signal);
|
|
3252
|
+
}
|
|
3253
|
+
async getDetails() {
|
|
3254
|
+
return describeSelectedRemoteCandidate(this._connection.currentConnection);
|
|
3255
|
+
}
|
|
3256
|
+
async getStats() {
|
|
3257
|
+
return createRtcTransportStats(this._connection.currentConnection, this._options.topic);
|
|
3258
|
+
}
|
|
3259
|
+
};
|
|
3243
3260
|
|
|
3244
|
-
// packages/core/mesh/network-manager/src/transport/
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3261
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/utils.ts
|
|
3262
|
+
var chooseInitiatorPeer = (peer1Key, peer2Key) => peer1Key < peer2Key ? peer1Key : peer2Key;
|
|
3263
|
+
var areSdpEqual = (sdp1, sdp2) => {
|
|
3264
|
+
const sdp1Lines = deduplicatedSdpLines(sdp1);
|
|
3265
|
+
const sdp2Lines = deduplicatedSdpLines(sdp2);
|
|
3266
|
+
if (sdp1Lines.length !== sdp2Lines.length) {
|
|
3267
|
+
return false;
|
|
3268
|
+
}
|
|
3269
|
+
return sdp1Lines.every((line, idx) => line === sdp2Lines[idx]);
|
|
3270
|
+
};
|
|
3271
|
+
var deduplicatedSdpLines = (sdp) => {
|
|
3272
|
+
const deduplicatedLines = [];
|
|
3273
|
+
const seenLines = [];
|
|
3274
|
+
for (const line of sdp.split("\r\n")) {
|
|
3275
|
+
if (line.startsWith("m")) {
|
|
3276
|
+
seenLines.length = 0;
|
|
3277
|
+
}
|
|
3278
|
+
if (seenLines.includes(line)) {
|
|
3279
|
+
continue;
|
|
3280
|
+
}
|
|
3281
|
+
seenLines.push(line);
|
|
3282
|
+
deduplicatedLines.push(line);
|
|
3258
3283
|
}
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3284
|
+
return deduplicatedLines;
|
|
3285
|
+
};
|
|
3286
|
+
|
|
3287
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-peer-connection.ts
|
|
3288
|
+
function _ts_decorate6(decorators, target, key, desc) {
|
|
3289
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3290
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3291
|
+
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;
|
|
3292
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3293
|
+
}
|
|
3294
|
+
var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-peer-connection.ts";
|
|
3295
|
+
var RtcPeerConnection = class {
|
|
3296
|
+
constructor(_factory, _options) {
|
|
3297
|
+
this._factory = _factory;
|
|
3298
|
+
this._options = _options;
|
|
3299
|
+
this._channelCreatedCallbacks = /* @__PURE__ */ new Map();
|
|
3300
|
+
this._transportChannels = /* @__PURE__ */ new Map();
|
|
3301
|
+
this._dataChannels = /* @__PURE__ */ new Map();
|
|
3302
|
+
this._readyForCandidates = new Trigger3();
|
|
3303
|
+
this._offerProcessingMutex = new Mutex2();
|
|
3304
|
+
this._initiator = chooseInitiatorPeer(_options.ownPeerKey, _options.remotePeerKey) === _options.ownPeerKey;
|
|
3305
|
+
}
|
|
3306
|
+
get transportChannelCount() {
|
|
3307
|
+
return this._transportChannels.size;
|
|
3308
|
+
}
|
|
3309
|
+
get currentConnection() {
|
|
3310
|
+
return this._connection;
|
|
3311
|
+
}
|
|
3312
|
+
async createDataChannel(topic) {
|
|
3313
|
+
const connection = await this._openConnection();
|
|
3314
|
+
if (!this._transportChannels.has(topic)) {
|
|
3315
|
+
if (!this._transportChannels.size) {
|
|
3316
|
+
this._lockAndCloseConnection();
|
|
3317
|
+
}
|
|
3318
|
+
throw new Error("Transport closed while connection was being open");
|
|
3319
|
+
}
|
|
3320
|
+
if (this._initiator) {
|
|
3321
|
+
const channel = connection.createDataChannel(topic);
|
|
3322
|
+
this._dataChannels.set(topic, channel);
|
|
3323
|
+
return channel;
|
|
3324
|
+
} else {
|
|
3325
|
+
const existingChannel = this._dataChannels.get(topic);
|
|
3326
|
+
if (existingChannel) {
|
|
3327
|
+
return existingChannel;
|
|
3328
|
+
}
|
|
3329
|
+
log13("waiting for initiator-peer to open a data channel", void 0, {
|
|
3330
|
+
F: __dxlog_file14,
|
|
3331
|
+
L: 90,
|
|
3332
|
+
S: this,
|
|
3333
|
+
C: (f, a) => f(...a)
|
|
3279
3334
|
});
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
next({
|
|
3286
|
-
signal: {
|
|
3287
|
-
payload: signal
|
|
3288
|
-
}
|
|
3289
|
-
});
|
|
3290
|
-
},
|
|
3291
|
-
iceProvider: this._iceProvider
|
|
3335
|
+
return new Promise((resolve, reject) => {
|
|
3336
|
+
this._channelCreatedCallbacks.set(topic, {
|
|
3337
|
+
resolve,
|
|
3338
|
+
reject
|
|
3339
|
+
});
|
|
3292
3340
|
});
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3341
|
+
}
|
|
3342
|
+
}
|
|
3343
|
+
createTransportChannel(options) {
|
|
3344
|
+
const channel = new RtcTransportChannel(this, options);
|
|
3345
|
+
this._transportChannels.set(options.topic, channel);
|
|
3346
|
+
channel.closed.on(() => {
|
|
3347
|
+
this._transportChannels.delete(options.topic);
|
|
3348
|
+
if (this._transportChannels.size === 0) {
|
|
3349
|
+
this._lockAndCloseConnection();
|
|
3350
|
+
}
|
|
3351
|
+
});
|
|
3352
|
+
return channel;
|
|
3353
|
+
}
|
|
3354
|
+
async _openConnection() {
|
|
3355
|
+
if (this._connection) {
|
|
3356
|
+
return this._connection;
|
|
3357
|
+
}
|
|
3358
|
+
log13("initializing connection...", () => ({
|
|
3359
|
+
remotePeer: this._options.remotePeerKey
|
|
3360
|
+
}), {
|
|
3361
|
+
F: __dxlog_file14,
|
|
3362
|
+
L: 115,
|
|
3363
|
+
S: this,
|
|
3364
|
+
C: (f, a) => f(...a)
|
|
3365
|
+
});
|
|
3366
|
+
const config = await this._loadConnectionConfig();
|
|
3367
|
+
const connection = await this._factory.createConnection(config);
|
|
3368
|
+
const iceCandidateErrors = [];
|
|
3369
|
+
Object.assign(connection, {
|
|
3370
|
+
onnegotiationneeded: async () => {
|
|
3371
|
+
invariant12(this._initiator, void 0, {
|
|
3372
|
+
F: __dxlog_file14,
|
|
3373
|
+
L: 130,
|
|
3374
|
+
S: this,
|
|
3375
|
+
A: [
|
|
3376
|
+
"this._initiator",
|
|
3377
|
+
""
|
|
3378
|
+
]
|
|
3379
|
+
});
|
|
3380
|
+
if (connection !== this._connection) {
|
|
3381
|
+
this._onConnectionCallbackAfterClose("onnegotiationneeded", connection);
|
|
3382
|
+
return;
|
|
3297
3383
|
}
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
}
|
|
3384
|
+
log13("onnegotiationneeded", void 0, {
|
|
3385
|
+
F: __dxlog_file14,
|
|
3386
|
+
L: 137,
|
|
3387
|
+
S: this,
|
|
3388
|
+
C: (f, a) => f(...a)
|
|
3304
3389
|
});
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
connection
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3390
|
+
try {
|
|
3391
|
+
const offer = await connection.createOffer();
|
|
3392
|
+
await connection.setLocalDescription(offer);
|
|
3393
|
+
await this._sendDescription(connection, offer);
|
|
3394
|
+
} catch (err) {
|
|
3395
|
+
this._lockAndAbort(connection, err);
|
|
3396
|
+
}
|
|
3397
|
+
},
|
|
3398
|
+
// When ICE candidate identified (should be sent to remote peer) and when ICE gathering finalized.
|
|
3399
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidate_event
|
|
3400
|
+
onicecandidate: async (event) => {
|
|
3401
|
+
if (connection !== this._connection) {
|
|
3402
|
+
this._onConnectionCallbackAfterClose("onicecandidate", connection);
|
|
3403
|
+
return;
|
|
3404
|
+
}
|
|
3405
|
+
if (event.candidate) {
|
|
3406
|
+
log13("onicecandidate", {
|
|
3407
|
+
candidate: event.candidate.candidate
|
|
3408
|
+
}, {
|
|
3409
|
+
F: __dxlog_file14,
|
|
3410
|
+
L: 156,
|
|
3411
|
+
S: this,
|
|
3412
|
+
C: (f, a) => f(...a)
|
|
3413
|
+
});
|
|
3414
|
+
await this._sendIceCandidate(event.candidate);
|
|
3415
|
+
} else {
|
|
3416
|
+
log13("onicecandidate gathering complete", void 0, {
|
|
3417
|
+
F: __dxlog_file14,
|
|
3418
|
+
L: 159,
|
|
3419
|
+
S: this,
|
|
3420
|
+
C: (f, a) => f(...a)
|
|
3421
|
+
});
|
|
3422
|
+
}
|
|
3423
|
+
},
|
|
3424
|
+
// When error occurs while performing ICE negotiations through a STUN or TURN server.
|
|
3425
|
+
// It's ok for some candidates to fail if a working pair is eventually found.
|
|
3426
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidateerror_event
|
|
3427
|
+
onicecandidateerror: (event) => {
|
|
3428
|
+
const { url, errorCode, errorText } = event;
|
|
3429
|
+
iceCandidateErrors.push({
|
|
3430
|
+
url,
|
|
3431
|
+
errorCode,
|
|
3432
|
+
errorText
|
|
3312
3433
|
});
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3434
|
+
},
|
|
3435
|
+
// When possible error during ICE gathering.
|
|
3436
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceconnectionstatechange_event
|
|
3437
|
+
oniceconnectionstatechange: () => {
|
|
3438
|
+
if (connection !== this._connection) {
|
|
3439
|
+
this._onConnectionCallbackAfterClose("oniceconnectionstatechange", connection);
|
|
3440
|
+
return;
|
|
3441
|
+
}
|
|
3442
|
+
log13("oniceconnectionstatechange", {
|
|
3443
|
+
state: connection.iceConnectionState
|
|
3444
|
+
}, {
|
|
3445
|
+
F: __dxlog_file14,
|
|
3446
|
+
L: 179,
|
|
3447
|
+
S: this,
|
|
3448
|
+
C: (f, a) => f(...a)
|
|
3449
|
+
});
|
|
3450
|
+
if (connection.iceConnectionState === "failed") {
|
|
3451
|
+
this._lockAndAbort(connection, createIceFailureError(iceCandidateErrors));
|
|
3452
|
+
}
|
|
3453
|
+
},
|
|
3454
|
+
// When new track (or channel) is added.
|
|
3455
|
+
// State: { new, connecting, connected, disconnected, failed, closed }
|
|
3456
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionstatechange_event
|
|
3457
|
+
onconnectionstatechange: () => {
|
|
3458
|
+
if (connection !== this._connection) {
|
|
3459
|
+
if (connection.connectionState !== "closed" && connection.connectionState !== "failed") {
|
|
3460
|
+
this._onConnectionCallbackAfterClose("onconnectionstatechange", connection);
|
|
3319
3461
|
}
|
|
3462
|
+
return;
|
|
3463
|
+
}
|
|
3464
|
+
log13("onconnectionstatechange", {
|
|
3465
|
+
state: connection.connectionState
|
|
3466
|
+
}, {
|
|
3467
|
+
F: __dxlog_file14,
|
|
3468
|
+
L: 196,
|
|
3469
|
+
S: this,
|
|
3470
|
+
C: (f, a) => f(...a)
|
|
3320
3471
|
});
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3472
|
+
if (connection.connectionState === "failed") {
|
|
3473
|
+
this._lockAndAbort(connection, new Error("Connection failed."));
|
|
3474
|
+
}
|
|
3475
|
+
},
|
|
3476
|
+
onsignalingstatechange: () => {
|
|
3477
|
+
log13("onsignalingstatechange", {
|
|
3478
|
+
state: connection.signalingState
|
|
3479
|
+
}, {
|
|
3480
|
+
F: __dxlog_file14,
|
|
3481
|
+
L: 203,
|
|
3482
|
+
S: this,
|
|
3483
|
+
C: (f, a) => f(...a)
|
|
3484
|
+
});
|
|
3485
|
+
},
|
|
3486
|
+
// When channel is added to connection.
|
|
3487
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/datachannel_event
|
|
3488
|
+
ondatachannel: (event) => {
|
|
3489
|
+
invariant12(!this._initiator, "Initiator is expected to create data channels.", {
|
|
3490
|
+
F: __dxlog_file14,
|
|
3491
|
+
L: 209,
|
|
3492
|
+
S: this,
|
|
3493
|
+
A: [
|
|
3494
|
+
"!this._initiator",
|
|
3495
|
+
"'Initiator is expected to create data channels.'"
|
|
3496
|
+
]
|
|
3497
|
+
});
|
|
3498
|
+
if (connection !== this._connection) {
|
|
3499
|
+
this._onConnectionCallbackAfterClose("ondatachannel", connection);
|
|
3500
|
+
return;
|
|
3501
|
+
}
|
|
3502
|
+
log13("ondatachannel", {
|
|
3503
|
+
label: event.channel.label
|
|
3504
|
+
}, {
|
|
3505
|
+
F: __dxlog_file14,
|
|
3506
|
+
L: 216,
|
|
3507
|
+
S: this,
|
|
3508
|
+
C: (f, a) => f(...a)
|
|
3509
|
+
});
|
|
3510
|
+
this._dataChannels.set(event.channel.label, event.channel);
|
|
3511
|
+
const pendingCallback = this._channelCreatedCallbacks.get(event.channel.label);
|
|
3512
|
+
if (pendingCallback) {
|
|
3513
|
+
this._channelCreatedCallbacks.delete(event.channel.label);
|
|
3514
|
+
pendingCallback.resolve(event.channel);
|
|
3515
|
+
}
|
|
3516
|
+
}
|
|
3331
3517
|
});
|
|
3332
|
-
|
|
3518
|
+
this._connection = connection;
|
|
3519
|
+
this._readyForCandidates.reset();
|
|
3520
|
+
await this._factory.initConnection(connection, {
|
|
3521
|
+
initiator: this._initiator
|
|
3522
|
+
});
|
|
3523
|
+
return this._connection;
|
|
3333
3524
|
}
|
|
3334
|
-
|
|
3335
|
-
|
|
3525
|
+
_lockAndAbort(connection, error) {
|
|
3526
|
+
this._abortConnection(connection, error);
|
|
3527
|
+
}
|
|
3528
|
+
_abortConnection(connection, error) {
|
|
3529
|
+
if (connection !== this._connection) {
|
|
3530
|
+
log13.error("attempted to abort an inactive connection", {
|
|
3531
|
+
error
|
|
3532
|
+
}, {
|
|
3533
|
+
F: __dxlog_file14,
|
|
3534
|
+
L: 241,
|
|
3535
|
+
S: this,
|
|
3536
|
+
C: (f, a) => f(...a)
|
|
3537
|
+
});
|
|
3538
|
+
this._safeCloseConnection(connection);
|
|
3539
|
+
return;
|
|
3540
|
+
}
|
|
3541
|
+
for (const [topic, pendingCallback] of this._channelCreatedCallbacks.entries()) {
|
|
3542
|
+
pendingCallback.reject(error);
|
|
3543
|
+
this._transportChannels.delete(topic);
|
|
3544
|
+
}
|
|
3545
|
+
this._channelCreatedCallbacks.clear();
|
|
3546
|
+
for (const channel of this._transportChannels.values()) {
|
|
3547
|
+
channel.onConnectionError(error);
|
|
3548
|
+
}
|
|
3549
|
+
this._transportChannels.clear();
|
|
3550
|
+
this._safeCloseConnection();
|
|
3551
|
+
log13("connection aborted", {
|
|
3552
|
+
reason: error.message
|
|
3553
|
+
}, {
|
|
3336
3554
|
F: __dxlog_file14,
|
|
3337
|
-
L:
|
|
3555
|
+
L: 255,
|
|
3338
3556
|
S: this,
|
|
3339
|
-
|
|
3340
|
-
"this.transports.has(proxyId)",
|
|
3341
|
-
""
|
|
3342
|
-
]
|
|
3557
|
+
C: (f, a) => f(...a)
|
|
3343
3558
|
});
|
|
3344
|
-
await this.transports.get(proxyId).transport.onSignal(signal);
|
|
3345
3559
|
}
|
|
3346
|
-
|
|
3347
|
-
invariant12(this.
|
|
3560
|
+
_lockAndCloseConnection() {
|
|
3561
|
+
invariant12(this._transportChannels.size === 0, void 0, {
|
|
3348
3562
|
F: __dxlog_file14,
|
|
3349
|
-
L:
|
|
3563
|
+
L: 260,
|
|
3350
3564
|
S: this,
|
|
3351
3565
|
A: [
|
|
3352
|
-
"this.
|
|
3566
|
+
"this._transportChannels.size === 0",
|
|
3353
3567
|
""
|
|
3354
3568
|
]
|
|
3355
3569
|
});
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3570
|
+
if (this._connection) {
|
|
3571
|
+
this._safeCloseConnection();
|
|
3572
|
+
log13("connection closed", void 0, {
|
|
3573
|
+
F: __dxlog_file14,
|
|
3574
|
+
L: 263,
|
|
3575
|
+
S: this,
|
|
3576
|
+
C: (f, a) => f(...a)
|
|
3577
|
+
});
|
|
3578
|
+
}
|
|
3359
3579
|
}
|
|
3360
|
-
async
|
|
3361
|
-
|
|
3580
|
+
async onSignal(signal) {
|
|
3581
|
+
const connection = this._connection;
|
|
3582
|
+
if (!connection) {
|
|
3583
|
+
log13.warn("a signal ignored because the connection was closed", {
|
|
3584
|
+
type: signal.payload.data.type
|
|
3585
|
+
}, {
|
|
3586
|
+
F: __dxlog_file14,
|
|
3587
|
+
L: 271,
|
|
3588
|
+
S: this,
|
|
3589
|
+
C: (f, a) => f(...a)
|
|
3590
|
+
});
|
|
3591
|
+
return;
|
|
3592
|
+
}
|
|
3593
|
+
const data = signal.payload.data;
|
|
3594
|
+
switch (data.type) {
|
|
3595
|
+
case "offer": {
|
|
3596
|
+
await this._offerProcessingMutex.executeSynchronized(async () => {
|
|
3597
|
+
if (isRemoteDescriptionSet(connection, data)) {
|
|
3598
|
+
return;
|
|
3599
|
+
}
|
|
3600
|
+
if (connection.connectionState !== "new") {
|
|
3601
|
+
this._abortConnection(connection, new Error(`Received an offer in ${connection.connectionState}.`));
|
|
3602
|
+
return;
|
|
3603
|
+
}
|
|
3604
|
+
try {
|
|
3605
|
+
await connection.setRemoteDescription({
|
|
3606
|
+
type: data.type,
|
|
3607
|
+
sdp: data.sdp
|
|
3608
|
+
});
|
|
3609
|
+
const answer = await connection.createAnswer();
|
|
3610
|
+
await connection.setLocalDescription(answer);
|
|
3611
|
+
await this._sendDescription(connection, answer);
|
|
3612
|
+
this._onSessionNegotiated(connection);
|
|
3613
|
+
} catch (err) {
|
|
3614
|
+
this._abortConnection(connection, new Error("Error handling a remote offer.", {
|
|
3615
|
+
cause: err
|
|
3616
|
+
}));
|
|
3617
|
+
}
|
|
3618
|
+
});
|
|
3619
|
+
break;
|
|
3620
|
+
}
|
|
3621
|
+
case "answer":
|
|
3622
|
+
await this._offerProcessingMutex.executeSynchronized(async () => {
|
|
3623
|
+
try {
|
|
3624
|
+
if (isRemoteDescriptionSet(connection, data)) {
|
|
3625
|
+
return;
|
|
3626
|
+
}
|
|
3627
|
+
if (connection.signalingState !== "have-local-offer") {
|
|
3628
|
+
this._abortConnection(connection, new Error(`Unexpected answer from remote peer, signalingState was ${connection.signalingState}.`));
|
|
3629
|
+
return;
|
|
3630
|
+
}
|
|
3631
|
+
await connection.setRemoteDescription({
|
|
3632
|
+
type: data.type,
|
|
3633
|
+
sdp: data.sdp
|
|
3634
|
+
});
|
|
3635
|
+
this._onSessionNegotiated(connection);
|
|
3636
|
+
} catch (err) {
|
|
3637
|
+
this._abortConnection(connection, new Error("Error handling a remote answer.", {
|
|
3638
|
+
cause: err
|
|
3639
|
+
}));
|
|
3640
|
+
}
|
|
3641
|
+
});
|
|
3642
|
+
break;
|
|
3643
|
+
case "candidate":
|
|
3644
|
+
void this._processIceCandidate(connection, data.candidate);
|
|
3645
|
+
break;
|
|
3646
|
+
default:
|
|
3647
|
+
this._abortConnection(connection, new Error(`Unknown signal type ${data.type}.`));
|
|
3648
|
+
break;
|
|
3649
|
+
}
|
|
3650
|
+
log13("signal processed", {
|
|
3651
|
+
type: data.type
|
|
3652
|
+
}, {
|
|
3362
3653
|
F: __dxlog_file14,
|
|
3363
|
-
L:
|
|
3654
|
+
L: 330,
|
|
3364
3655
|
S: this,
|
|
3365
|
-
|
|
3366
|
-
"this.transports.has(proxyId)",
|
|
3367
|
-
""
|
|
3368
|
-
]
|
|
3656
|
+
C: (f, a) => f(...a)
|
|
3369
3657
|
});
|
|
3370
|
-
return {
|
|
3371
|
-
stats: await this.transports.get(proxyId).transport.getStats()
|
|
3372
|
-
};
|
|
3373
3658
|
}
|
|
3374
|
-
async
|
|
3375
|
-
|
|
3376
|
-
|
|
3659
|
+
async _processIceCandidate(connection, candidate) {
|
|
3660
|
+
try {
|
|
3661
|
+
await this._readyForCandidates.wait();
|
|
3662
|
+
if (connection === this._connection) {
|
|
3663
|
+
log13("adding ice candidate", {
|
|
3664
|
+
candidate
|
|
3665
|
+
}, {
|
|
3666
|
+
F: __dxlog_file14,
|
|
3667
|
+
L: 338,
|
|
3668
|
+
S: this,
|
|
3669
|
+
C: (f, a) => f(...a)
|
|
3670
|
+
});
|
|
3671
|
+
await connection.addIceCandidate(candidate);
|
|
3672
|
+
}
|
|
3673
|
+
} catch (err) {
|
|
3674
|
+
log13.catch(err, void 0, {
|
|
3675
|
+
F: __dxlog_file14,
|
|
3676
|
+
L: 342,
|
|
3677
|
+
S: this,
|
|
3678
|
+
C: (f, a) => f(...a)
|
|
3679
|
+
});
|
|
3680
|
+
}
|
|
3681
|
+
}
|
|
3682
|
+
_onSessionNegotiated(connection) {
|
|
3683
|
+
if (connection === this._connection) {
|
|
3684
|
+
log13("ready to process ice candidates", void 0, {
|
|
3685
|
+
F: __dxlog_file14,
|
|
3686
|
+
L: 348,
|
|
3687
|
+
S: this,
|
|
3688
|
+
C: (f, a) => f(...a)
|
|
3689
|
+
});
|
|
3690
|
+
this._readyForCandidates.wake();
|
|
3691
|
+
} else {
|
|
3692
|
+
log13.warn("session was negotiated after connection became inactive", void 0, {
|
|
3377
3693
|
F: __dxlog_file14,
|
|
3378
|
-
L:
|
|
3694
|
+
L: 351,
|
|
3379
3695
|
S: this,
|
|
3380
3696
|
C: (f, a) => f(...a)
|
|
3381
3697
|
});
|
|
3382
3698
|
}
|
|
3383
|
-
|
|
3699
|
+
}
|
|
3700
|
+
_onConnectionCallbackAfterClose(callback, connection) {
|
|
3701
|
+
log13.warn("callback invoked after a connection was destroyed, this is probably a bug", {
|
|
3702
|
+
callback,
|
|
3703
|
+
state: connection.connectionState
|
|
3704
|
+
}, {
|
|
3384
3705
|
F: __dxlog_file14,
|
|
3385
|
-
L:
|
|
3706
|
+
L: 356,
|
|
3386
3707
|
S: this,
|
|
3387
|
-
|
|
3388
|
-
"this.transports.has(proxyId)",
|
|
3389
|
-
""
|
|
3390
|
-
]
|
|
3708
|
+
C: (f, a) => f(...a)
|
|
3391
3709
|
});
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3710
|
+
this._safeCloseConnection(connection);
|
|
3711
|
+
}
|
|
3712
|
+
_safeCloseConnection(connection = this._connection) {
|
|
3713
|
+
const resetFields = this._connection && connection === this._connection;
|
|
3714
|
+
try {
|
|
3715
|
+
connection?.close();
|
|
3716
|
+
} catch (err) {
|
|
3717
|
+
log13.catch(err, void 0, {
|
|
3718
|
+
F: __dxlog_file14,
|
|
3719
|
+
L: 368,
|
|
3720
|
+
S: this,
|
|
3721
|
+
C: (f, a) => f(...a)
|
|
3722
|
+
});
|
|
3723
|
+
}
|
|
3724
|
+
if (resetFields) {
|
|
3725
|
+
this._connection = void 0;
|
|
3726
|
+
this._dataChannels.clear();
|
|
3727
|
+
this._readyForCandidates.wake();
|
|
3728
|
+
void this._factory.onConnectionDestroyed().catch((err) => log13.catch(err, void 0, {
|
|
3729
|
+
F: __dxlog_file14,
|
|
3730
|
+
L: 374,
|
|
3731
|
+
S: this,
|
|
3732
|
+
C: (f, a) => f(...a)
|
|
3733
|
+
}));
|
|
3734
|
+
for (const [_, pendingCallback] of this._channelCreatedCallbacks.entries()) {
|
|
3735
|
+
pendingCallback.reject("Connection closed.");
|
|
3736
|
+
}
|
|
3737
|
+
this._channelCreatedCallbacks.clear();
|
|
3738
|
+
}
|
|
3739
|
+
}
|
|
3740
|
+
async _loadConnectionConfig() {
|
|
3741
|
+
const config = {
|
|
3742
|
+
...this._options.webrtcConfig
|
|
3743
|
+
};
|
|
3744
|
+
try {
|
|
3745
|
+
const providedIceServers = await this._options.iceProvider?.getIceServers() ?? [];
|
|
3746
|
+
if (providedIceServers.length > 0) {
|
|
3747
|
+
config.iceServers = [
|
|
3748
|
+
...config.iceServers ?? [],
|
|
3749
|
+
...providedIceServers
|
|
3750
|
+
];
|
|
3751
|
+
}
|
|
3752
|
+
} catch (error) {
|
|
3753
|
+
log13.catch(error, void 0, {
|
|
3754
|
+
F: __dxlog_file14,
|
|
3755
|
+
L: 390,
|
|
3756
|
+
S: this,
|
|
3757
|
+
C: (f, a) => f(...a)
|
|
3758
|
+
});
|
|
3759
|
+
}
|
|
3760
|
+
return config;
|
|
3761
|
+
}
|
|
3762
|
+
async _sendIceCandidate(candidate) {
|
|
3763
|
+
try {
|
|
3764
|
+
await this._options.sendSignal({
|
|
3765
|
+
payload: {
|
|
3766
|
+
data: {
|
|
3767
|
+
type: "candidate",
|
|
3768
|
+
candidate: {
|
|
3769
|
+
candidate: candidate.candidate,
|
|
3770
|
+
// These fields never seem to be not null, but connecting to Chrome doesn't work if they are.
|
|
3771
|
+
sdpMLineIndex: candidate.sdpMLineIndex ?? "0",
|
|
3772
|
+
sdpMid: candidate.sdpMid ?? "0"
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
});
|
|
3777
|
+
} catch (err) {
|
|
3778
|
+
log13.warn("signaling error", {
|
|
3779
|
+
err
|
|
3780
|
+
}, {
|
|
3781
|
+
F: __dxlog_file14,
|
|
3782
|
+
L: 411,
|
|
3783
|
+
S: this,
|
|
3784
|
+
C: (f, a) => f(...a)
|
|
3397
3785
|
});
|
|
3398
3786
|
}
|
|
3399
3787
|
}
|
|
3400
|
-
async
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
if (this.transports.get(proxyId)) {
|
|
3404
|
-
this.transports.get(proxyId).state = "CLOSED";
|
|
3788
|
+
async _sendDescription(connection, description) {
|
|
3789
|
+
if (connection !== this._connection) {
|
|
3790
|
+
return;
|
|
3405
3791
|
}
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3792
|
+
const data = {
|
|
3793
|
+
type: description.type,
|
|
3794
|
+
sdp: description.sdp
|
|
3795
|
+
};
|
|
3796
|
+
await this._options.sendSignal({
|
|
3797
|
+
payload: {
|
|
3798
|
+
data
|
|
3799
|
+
}
|
|
3411
3800
|
});
|
|
3412
3801
|
}
|
|
3802
|
+
get _connectionInfo() {
|
|
3803
|
+
const connectionInfo = this._connection && {
|
|
3804
|
+
connectionState: this._connection.connectionState,
|
|
3805
|
+
iceConnectionState: this._connection.iceConnectionState,
|
|
3806
|
+
iceGatheringState: this._connection.iceGatheringState,
|
|
3807
|
+
signalingState: this._connection.signalingState,
|
|
3808
|
+
remoteDescription: this._connection.remoteDescription,
|
|
3809
|
+
localDescription: this._connection.localDescription
|
|
3810
|
+
};
|
|
3811
|
+
return {
|
|
3812
|
+
...connectionInfo,
|
|
3813
|
+
ts: Date.now(),
|
|
3814
|
+
remotePeerKey: this._options.remotePeerKey,
|
|
3815
|
+
channels: [
|
|
3816
|
+
...this._transportChannels.keys()
|
|
3817
|
+
].map((topic) => topic),
|
|
3818
|
+
config: this._connection?.getConfiguration()
|
|
3819
|
+
};
|
|
3820
|
+
}
|
|
3821
|
+
get _loggerContext() {
|
|
3822
|
+
return {
|
|
3823
|
+
ownPeerKey: this._options.ownPeerKey,
|
|
3824
|
+
remotePeerKey: this._options.remotePeerKey,
|
|
3825
|
+
initiator: this._initiator,
|
|
3826
|
+
channels: this._transportChannels.size
|
|
3827
|
+
};
|
|
3828
|
+
}
|
|
3829
|
+
};
|
|
3830
|
+
_ts_decorate6([
|
|
3831
|
+
synchronized5
|
|
3832
|
+
], RtcPeerConnection.prototype, "_openConnection", null);
|
|
3833
|
+
_ts_decorate6([
|
|
3834
|
+
synchronized5
|
|
3835
|
+
], RtcPeerConnection.prototype, "_lockAndAbort", null);
|
|
3836
|
+
_ts_decorate6([
|
|
3837
|
+
synchronized5
|
|
3838
|
+
], RtcPeerConnection.prototype, "_lockAndCloseConnection", null);
|
|
3839
|
+
_ts_decorate6([
|
|
3840
|
+
synchronized5
|
|
3841
|
+
], RtcPeerConnection.prototype, "onSignal", null);
|
|
3842
|
+
_ts_decorate6([
|
|
3843
|
+
trace4.info()
|
|
3844
|
+
], RtcPeerConnection.prototype, "_connectionInfo", null);
|
|
3845
|
+
_ts_decorate6([
|
|
3846
|
+
logInfo4
|
|
3847
|
+
], RtcPeerConnection.prototype, "_loggerContext", null);
|
|
3848
|
+
RtcPeerConnection = _ts_decorate6([
|
|
3849
|
+
trace4.resource()
|
|
3850
|
+
], RtcPeerConnection);
|
|
3851
|
+
var isRemoteDescriptionSet = (connection, data) => {
|
|
3852
|
+
if (!connection.remoteDescription?.type || connection.remoteDescription?.type !== data.type) {
|
|
3853
|
+
return false;
|
|
3854
|
+
}
|
|
3855
|
+
return areSdpEqual(connection.remoteDescription.sdp, data.sdp);
|
|
3856
|
+
};
|
|
3857
|
+
var createIceFailureError = (details) => {
|
|
3858
|
+
const candidateErrors = details.map(({ url, errorCode, errorText }) => `${errorCode} ${url}: ${errorText}`);
|
|
3859
|
+
return new ConnectivityError3(`ICE failed:
|
|
3860
|
+
${candidateErrors.join("\n")}`);
|
|
3861
|
+
};
|
|
3862
|
+
|
|
3863
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-factory.ts
|
|
3864
|
+
var createRtcTransportFactory = (webrtcConfig, iceProvider) => {
|
|
3865
|
+
const connectionFactory = getRtcConnectionFactory();
|
|
3866
|
+
return {
|
|
3867
|
+
createTransport: (options) => {
|
|
3868
|
+
const connection = new RtcPeerConnection(connectionFactory, {
|
|
3869
|
+
ownPeerKey: options.ownPeerKey,
|
|
3870
|
+
remotePeerKey: options.remotePeerKey,
|
|
3871
|
+
sendSignal: options.sendSignal,
|
|
3872
|
+
webrtcConfig,
|
|
3873
|
+
iceProvider
|
|
3874
|
+
});
|
|
3875
|
+
return connection.createTransportChannel(options);
|
|
3876
|
+
}
|
|
3877
|
+
};
|
|
3413
3878
|
};
|
|
3414
3879
|
|
|
3415
|
-
// packages/core/mesh/network-manager/src/transport/
|
|
3880
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-proxy.ts
|
|
3416
3881
|
import { Writable } from "@dxos/node-std/stream";
|
|
3417
|
-
import { Event as
|
|
3418
|
-
import {
|
|
3882
|
+
import { Event as Event8, scheduleTask as scheduleTask4 } from "@dxos/async";
|
|
3883
|
+
import { Resource as Resource2 } from "@dxos/context";
|
|
3419
3884
|
import { ErrorStream as ErrorStream5 } from "@dxos/debug";
|
|
3420
3885
|
import { invariant as invariant13 } from "@dxos/invariant";
|
|
3421
|
-
import { PublicKey as
|
|
3886
|
+
import { PublicKey as PublicKey10 } from "@dxos/keys";
|
|
3422
3887
|
import { log as log14 } from "@dxos/log";
|
|
3423
|
-
import { ConnectionResetError as
|
|
3424
|
-
import { ConnectionState as
|
|
3888
|
+
import { ConnectionResetError as ConnectionResetError2, ConnectivityError as ConnectivityError4, TimeoutError as TimeoutError3 } from "@dxos/protocols";
|
|
3889
|
+
import { ConnectionState as ConnectionState3 } from "@dxos/protocols/proto/dxos/mesh/bridge";
|
|
3425
3890
|
import { arrayToBuffer } from "@dxos/util";
|
|
3426
|
-
var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/
|
|
3891
|
+
var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-proxy.ts";
|
|
3427
3892
|
var RPC_TIMEOUT = 1e4;
|
|
3893
|
+
var CLOSE_RPC_TIMEOUT = 3e3;
|
|
3428
3894
|
var RESP_MIN_THRESHOLD = 500;
|
|
3429
|
-
var
|
|
3430
|
-
var SimplePeerTransportProxy = class {
|
|
3895
|
+
var RtcTransportProxy = class extends Resource2 {
|
|
3431
3896
|
constructor(_options) {
|
|
3897
|
+
super();
|
|
3432
3898
|
this._options = _options;
|
|
3433
|
-
this._proxyId =
|
|
3434
|
-
this.
|
|
3435
|
-
|
|
3436
|
-
L: 37
|
|
3437
|
-
});
|
|
3438
|
-
this._timeoutCount = 0;
|
|
3439
|
-
this.closed = new Event9();
|
|
3440
|
-
this.connected = new Event9();
|
|
3899
|
+
this._proxyId = PublicKey10.random();
|
|
3900
|
+
this.closed = new Event8();
|
|
3901
|
+
this.connected = new Event8();
|
|
3441
3902
|
this.errors = new ErrorStream5();
|
|
3442
|
-
this._closed = false;
|
|
3443
3903
|
}
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3904
|
+
async _open() {
|
|
3905
|
+
let stream;
|
|
3906
|
+
try {
|
|
3907
|
+
stream = this._options.bridgeService.open({
|
|
3908
|
+
proxyId: this._proxyId,
|
|
3909
|
+
remotePeerKey: this._options.remotePeerKey,
|
|
3910
|
+
ownPeerKey: this._options.ownPeerKey,
|
|
3911
|
+
topic: this._options.topic,
|
|
3912
|
+
initiator: this._options.initiator ?? false
|
|
3913
|
+
}, {
|
|
3914
|
+
timeout: RPC_TIMEOUT
|
|
3915
|
+
});
|
|
3916
|
+
} catch (error) {
|
|
3917
|
+
this.errors.raise(error);
|
|
3918
|
+
return;
|
|
3919
|
+
}
|
|
3920
|
+
this._serviceStream = stream;
|
|
3921
|
+
stream.waitUntilReady().then(() => {
|
|
3922
|
+
stream.subscribe(async (event) => {
|
|
3923
|
+
log14("rtc transport proxy event", event, {
|
|
3457
3924
|
F: __dxlog_file15,
|
|
3458
3925
|
L: 66,
|
|
3459
3926
|
S: this,
|
|
@@ -3466,20 +3933,34 @@ var SimplePeerTransportProxy = class {
|
|
|
3466
3933
|
} else if (event.signal) {
|
|
3467
3934
|
await this._handleSignal(event.signal);
|
|
3468
3935
|
}
|
|
3936
|
+
}, (err) => {
|
|
3937
|
+
log14("rtc bridge stream closed", {
|
|
3938
|
+
err
|
|
3939
|
+
}, {
|
|
3940
|
+
F: __dxlog_file15,
|
|
3941
|
+
L: 76,
|
|
3942
|
+
S: this,
|
|
3943
|
+
C: (f, a) => f(...a)
|
|
3944
|
+
});
|
|
3945
|
+
if (err) {
|
|
3946
|
+
this._raiseIfOpen(err);
|
|
3947
|
+
} else {
|
|
3948
|
+
void this.close();
|
|
3949
|
+
}
|
|
3469
3950
|
});
|
|
3470
|
-
const
|
|
3951
|
+
const connectorStream = new Writable({
|
|
3471
3952
|
write: (chunk, _, callback) => {
|
|
3472
|
-
const
|
|
3953
|
+
const sendStartMs = Date.now();
|
|
3473
3954
|
this._options.bridgeService.sendData({
|
|
3474
3955
|
proxyId: this._proxyId,
|
|
3475
3956
|
payload: chunk
|
|
3476
3957
|
}, {
|
|
3477
3958
|
timeout: RPC_TIMEOUT
|
|
3478
3959
|
}).then(() => {
|
|
3479
|
-
if (
|
|
3960
|
+
if (Date.now() - sendStartMs > RESP_MIN_THRESHOLD) {
|
|
3480
3961
|
log14("slow response, delaying callback", void 0, {
|
|
3481
3962
|
F: __dxlog_file15,
|
|
3482
|
-
L:
|
|
3963
|
+
L: 93,
|
|
3483
3964
|
S: this,
|
|
3484
3965
|
C: (f, a) => f(...a)
|
|
3485
3966
|
});
|
|
@@ -3487,60 +3968,41 @@ var SimplePeerTransportProxy = class {
|
|
|
3487
3968
|
} else {
|
|
3488
3969
|
callback();
|
|
3489
3970
|
}
|
|
3490
|
-
this._timeoutCount = 0;
|
|
3491
3971
|
}, (err) => {
|
|
3492
|
-
|
|
3493
|
-
|
|
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
|
-
}
|
|
3972
|
+
callback();
|
|
3973
|
+
this._raiseIfOpen(err);
|
|
3512
3974
|
});
|
|
3513
3975
|
}
|
|
3514
3976
|
});
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
err
|
|
3518
|
-
}, {
|
|
3519
|
-
F: __dxlog_file15,
|
|
3520
|
-
L: 114,
|
|
3521
|
-
S: this,
|
|
3522
|
-
C: (f, a) => f(...a)
|
|
3523
|
-
});
|
|
3977
|
+
connectorStream.on("error", (err) => {
|
|
3978
|
+
this._raiseIfOpen(err);
|
|
3524
3979
|
});
|
|
3525
|
-
this._options.stream.pipe(
|
|
3526
|
-
}, (error) =>
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3980
|
+
this._options.stream.pipe(connectorStream);
|
|
3981
|
+
}, (error) => {
|
|
3982
|
+
if (error) {
|
|
3983
|
+
this._raiseIfOpen(error);
|
|
3984
|
+
} else {
|
|
3985
|
+
void this.close();
|
|
3986
|
+
}
|
|
3987
|
+
});
|
|
3532
3988
|
}
|
|
3533
|
-
async
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3989
|
+
async _close() {
|
|
3990
|
+
try {
|
|
3991
|
+
await this._serviceStream?.close();
|
|
3992
|
+
this._serviceStream = void 0;
|
|
3993
|
+
} catch (err) {
|
|
3994
|
+
log14.catch(err, void 0, {
|
|
3995
|
+
F: __dxlog_file15,
|
|
3996
|
+
L: 128,
|
|
3997
|
+
S: this,
|
|
3998
|
+
C: (f, a) => f(...a)
|
|
3999
|
+
});
|
|
3537
4000
|
}
|
|
3538
|
-
await this._serviceStream.close();
|
|
3539
4001
|
try {
|
|
3540
4002
|
await this._options.bridgeService.close({
|
|
3541
4003
|
proxyId: this._proxyId
|
|
3542
4004
|
}, {
|
|
3543
|
-
timeout:
|
|
4005
|
+
timeout: CLOSE_RPC_TIMEOUT
|
|
3544
4006
|
});
|
|
3545
4007
|
} catch (err) {
|
|
3546
4008
|
log14.catch(err, void 0, {
|
|
@@ -3551,7 +4013,6 @@ var SimplePeerTransportProxy = class {
|
|
|
3551
4013
|
});
|
|
3552
4014
|
}
|
|
3553
4015
|
this.closed.emit();
|
|
3554
|
-
this._closed = true;
|
|
3555
4016
|
}
|
|
3556
4017
|
async onSignal(signal) {
|
|
3557
4018
|
this._options.bridgeService.sendSignal({
|
|
@@ -3559,581 +4020,347 @@ var SimplePeerTransportProxy = class {
|
|
|
3559
4020
|
signal
|
|
3560
4021
|
}, {
|
|
3561
4022
|
timeout: RPC_TIMEOUT
|
|
3562
|
-
}).catch((err) => this.
|
|
4023
|
+
}).catch((err) => this._raiseIfOpen(decodeError(err)));
|
|
3563
4024
|
}
|
|
3564
4025
|
async _handleConnection(connectionEvent) {
|
|
3565
4026
|
if (connectionEvent.error) {
|
|
3566
4027
|
this.errors.raise(decodeError(connectionEvent.error));
|
|
4028
|
+
return;
|
|
3567
4029
|
}
|
|
3568
4030
|
switch (connectionEvent.state) {
|
|
3569
|
-
case
|
|
4031
|
+
case ConnectionState3.CONNECTED: {
|
|
3570
4032
|
this.connected.emit();
|
|
3571
4033
|
break;
|
|
3572
4034
|
}
|
|
3573
|
-
case
|
|
4035
|
+
case ConnectionState3.CLOSED: {
|
|
3574
4036
|
await this.close();
|
|
3575
4037
|
break;
|
|
3576
4038
|
}
|
|
3577
4039
|
}
|
|
3578
4040
|
}
|
|
3579
4041
|
_handleData(dataEvent) {
|
|
3580
|
-
|
|
4042
|
+
try {
|
|
4043
|
+
this._options.stream.write(arrayToBuffer(dataEvent.payload));
|
|
4044
|
+
} catch (error) {
|
|
4045
|
+
this._raiseIfOpen(error);
|
|
4046
|
+
}
|
|
3581
4047
|
}
|
|
3582
4048
|
async _handleSignal(signalEvent) {
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
})).details;
|
|
3591
|
-
}
|
|
3592
|
-
async getStats() {
|
|
3593
|
-
return (await this._options.bridgeService.getStats({
|
|
3594
|
-
proxyId: this._proxyId
|
|
3595
|
-
}, {
|
|
3596
|
-
timeout: RPC_TIMEOUT
|
|
3597
|
-
})).stats;
|
|
3598
|
-
}
|
|
3599
|
-
/**
|
|
3600
|
-
* Called when underlying proxy service becomes unavailable.
|
|
3601
|
-
*/
|
|
3602
|
-
// TODO(burdon): Option on close method.
|
|
3603
|
-
forceClose() {
|
|
3604
|
-
void this._serviceStream.close();
|
|
3605
|
-
this.closed.emit();
|
|
3606
|
-
this._closed = true;
|
|
3607
|
-
}
|
|
3608
|
-
};
|
|
3609
|
-
var SimplePeerTransportProxyFactory = class {
|
|
3610
|
-
constructor() {
|
|
3611
|
-
this._connections = /* @__PURE__ */ new Set();
|
|
3612
|
-
}
|
|
3613
|
-
/**
|
|
3614
|
-
* Sets the current BridgeService to be used to open connections.
|
|
3615
|
-
* Calling this method will close any existing connections.
|
|
3616
|
-
*/
|
|
3617
|
-
setBridgeService(bridgeService) {
|
|
3618
|
-
this._bridgeService = bridgeService;
|
|
3619
|
-
for (const connection of this._connections) {
|
|
3620
|
-
connection.forceClose();
|
|
4049
|
+
try {
|
|
4050
|
+
await this._options.sendSignal(signalEvent.payload);
|
|
4051
|
+
} catch (error) {
|
|
4052
|
+
const type = signalEvent.payload.payload.data?.type;
|
|
4053
|
+
if (type === "offer" || type === "answer") {
|
|
4054
|
+
this._raiseIfOpen(new ConnectivityError4(`Session establishment failed: ${type} couldn't be sent.`));
|
|
4055
|
+
}
|
|
3621
4056
|
}
|
|
3622
|
-
return this;
|
|
3623
|
-
}
|
|
3624
|
-
createTransport(options) {
|
|
3625
|
-
invariant13(this._bridgeService, "SimplePeerTransportProxyFactory is not ready to open connections", {
|
|
3626
|
-
F: __dxlog_file15,
|
|
3627
|
-
L: 218,
|
|
3628
|
-
S: this,
|
|
3629
|
-
A: [
|
|
3630
|
-
"this._bridgeService",
|
|
3631
|
-
"'SimplePeerTransportProxyFactory is not ready to open connections'"
|
|
3632
|
-
]
|
|
3633
|
-
});
|
|
3634
|
-
const transport = new SimplePeerTransportProxy({
|
|
3635
|
-
...options,
|
|
3636
|
-
bridgeService: this._bridgeService
|
|
3637
|
-
});
|
|
3638
|
-
this._connections.add(transport);
|
|
3639
|
-
transport.closed.on(() => this._connections.delete(transport));
|
|
3640
|
-
return transport;
|
|
3641
|
-
}
|
|
3642
|
-
};
|
|
3643
|
-
var decodeError = (err) => {
|
|
3644
|
-
const message = typeof err === "string" ? err : err.message;
|
|
3645
|
-
if (message.includes("CONNECTION_RESET")) {
|
|
3646
|
-
return new ConnectionResetError3(message);
|
|
3647
|
-
} else if (message.includes("TIMEOUT")) {
|
|
3648
|
-
return new TimeoutError3(message);
|
|
3649
|
-
} else if (message.includes("PROTOCOL_ERROR")) {
|
|
3650
|
-
return new ProtocolError3(message);
|
|
3651
|
-
} else if (message.includes("CONNECTIVITY_ERROR")) {
|
|
3652
|
-
return new ConnectivityError3(message);
|
|
3653
|
-
} else if (message.includes("UNKNOWN_PROTOCOL_ERROR")) {
|
|
3654
|
-
return new UnknownProtocolError3(message);
|
|
3655
|
-
} else {
|
|
3656
|
-
return typeof err === "string" ? new Error(err) : err;
|
|
3657
|
-
}
|
|
3658
|
-
};
|
|
3659
|
-
|
|
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";
|
|
3664
|
-
import { invariant as invariant14 } from "@dxos/invariant";
|
|
3665
|
-
import { log as log15 } from "@dxos/log";
|
|
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;
|
|
3688
|
-
}
|
|
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();
|
|
3698
4057
|
}
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
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
|
-
}, {
|
|
3720
|
-
F: __dxlog_file16,
|
|
3721
|
-
L: 93,
|
|
3722
|
-
S: this,
|
|
3723
|
-
C: (f, a) => f(...a)
|
|
3724
|
-
});
|
|
3725
|
-
};
|
|
3726
|
-
this._peer.onconnectionstatechange = (event) => {
|
|
3727
|
-
log15.debug("peer.onconnectionstatechange", {
|
|
3728
|
-
event,
|
|
3729
|
-
peerConnectionState: this._peer?.connectionState,
|
|
3730
|
-
transportConnectionState: this._connected
|
|
4058
|
+
async getDetails() {
|
|
4059
|
+
try {
|
|
4060
|
+
const response = await this._options.bridgeService.getDetails({
|
|
4061
|
+
proxyId: this._proxyId
|
|
3731
4062
|
}, {
|
|
3732
|
-
|
|
3733
|
-
L: 97,
|
|
3734
|
-
S: this,
|
|
3735
|
-
C: (f, a) => f(...a)
|
|
4063
|
+
timeout: RPC_TIMEOUT
|
|
3736
4064
|
});
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
4065
|
+
return response.details;
|
|
4066
|
+
} catch (err) {
|
|
4067
|
+
return "bridge-svc unreachable";
|
|
4068
|
+
}
|
|
4069
|
+
}
|
|
4070
|
+
async getStats() {
|
|
4071
|
+
try {
|
|
4072
|
+
const response = await this._options.bridgeService.getStats({
|
|
4073
|
+
proxyId: this._proxyId
|
|
3741
4074
|
}, {
|
|
3742
|
-
|
|
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
|
-
}
|
|
3760
|
-
}
|
|
3761
|
-
});
|
|
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
|
-
});
|
|
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
|
-
]
|
|
3783
|
-
});
|
|
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)
|
|
3796
|
-
});
|
|
3797
|
-
this.errors.raise(new Error("invalid state: peer is initiator, but other peer not in state connecting"));
|
|
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);
|
|
3819
|
-
});
|
|
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)
|
|
4075
|
+
timeout: RPC_TIMEOUT
|
|
3826
4076
|
});
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
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);
|
|
4077
|
+
return response.stats;
|
|
4078
|
+
} catch (err) {
|
|
4079
|
+
return {
|
|
4080
|
+
bytesSent: 0,
|
|
4081
|
+
bytesReceived: 0,
|
|
4082
|
+
packetsSent: 0,
|
|
4083
|
+
packetsReceived: 0,
|
|
4084
|
+
rawStats: "bridge-svc unreachable"
|
|
3844
4085
|
};
|
|
3845
4086
|
}
|
|
3846
|
-
_LibDataChannelTransport._instanceCount++;
|
|
3847
4087
|
}
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
4088
|
+
_raiseIfOpen(error) {
|
|
4089
|
+
if (this.isOpen) {
|
|
4090
|
+
this.errors.raise(error);
|
|
4091
|
+
} else {
|
|
4092
|
+
log14.info("error swallowed because transport was closed", {
|
|
4093
|
+
message: error.message
|
|
4094
|
+
}, {
|
|
4095
|
+
F: __dxlog_file15,
|
|
4096
|
+
L: 215,
|
|
4097
|
+
S: this,
|
|
4098
|
+
C: (f, a) => f(...a)
|
|
4099
|
+
});
|
|
3852
4100
|
}
|
|
3853
4101
|
}
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
try {
|
|
3860
|
-
this._peer?.close();
|
|
3861
|
-
} catch (err) {
|
|
3862
|
-
this.errors.raise(err);
|
|
3863
|
-
}
|
|
3864
|
-
this._peer = void 0;
|
|
3865
|
-
this._closed = true;
|
|
4102
|
+
/**
|
|
4103
|
+
* Called when underlying proxy service becomes unavailable.
|
|
4104
|
+
*/
|
|
4105
|
+
forceClose() {
|
|
4106
|
+
void this._serviceStream?.close();
|
|
3866
4107
|
this.closed.emit();
|
|
3867
4108
|
}
|
|
4109
|
+
};
|
|
4110
|
+
var RtcTransportProxyFactory = class {
|
|
4111
|
+
constructor() {
|
|
4112
|
+
this._connections = /* @__PURE__ */ new Set();
|
|
4113
|
+
}
|
|
3868
4114
|
/**
|
|
3869
|
-
*
|
|
4115
|
+
* Sets the current BridgeService to be used to open connections.
|
|
4116
|
+
* Calling this method will close any existing connections.
|
|
3870
4117
|
*/
|
|
3871
|
-
|
|
3872
|
-
this.
|
|
3873
|
-
this.
|
|
3874
|
-
|
|
4118
|
+
setBridgeService(bridgeService) {
|
|
4119
|
+
this._bridgeService = bridgeService;
|
|
4120
|
+
for (const connection of this._connections) {
|
|
4121
|
+
connection.forceClose();
|
|
4122
|
+
}
|
|
4123
|
+
return this;
|
|
4124
|
+
}
|
|
4125
|
+
createTransport(options) {
|
|
4126
|
+
invariant13(this._bridgeService, "RtcTransportProxyFactory is not ready to open connections", {
|
|
4127
|
+
F: __dxlog_file15,
|
|
4128
|
+
L: 245,
|
|
4129
|
+
S: this,
|
|
4130
|
+
A: [
|
|
4131
|
+
"this._bridgeService",
|
|
4132
|
+
"'RtcTransportProxyFactory is not ready to open connections'"
|
|
4133
|
+
]
|
|
4134
|
+
});
|
|
4135
|
+
const transport = new RtcTransportProxy({
|
|
4136
|
+
...options,
|
|
4137
|
+
bridgeService: this._bridgeService
|
|
4138
|
+
});
|
|
4139
|
+
this._connections.add(transport);
|
|
4140
|
+
transport.closed.on(() => this._connections.delete(transport));
|
|
4141
|
+
return transport;
|
|
4142
|
+
}
|
|
4143
|
+
};
|
|
4144
|
+
var decodeError = (err) => {
|
|
4145
|
+
const message = typeof err === "string" ? err : err.message;
|
|
4146
|
+
if (message.includes("CONNECTION_RESET")) {
|
|
4147
|
+
return new ConnectionResetError2(message);
|
|
4148
|
+
} else if (message.includes("TIMEOUT")) {
|
|
4149
|
+
return new TimeoutError3(message);
|
|
4150
|
+
} else if (message.includes("CONNECTIVITY_ERROR")) {
|
|
4151
|
+
return new ConnectivityError4(message);
|
|
4152
|
+
} else {
|
|
4153
|
+
return typeof err === "string" ? new Error(err) : err;
|
|
4154
|
+
}
|
|
4155
|
+
};
|
|
4156
|
+
|
|
4157
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-service.ts
|
|
4158
|
+
import { Duplex as Duplex2 } from "@dxos/node-std/stream";
|
|
4159
|
+
import { Stream } from "@dxos/codec-protobuf";
|
|
4160
|
+
import { invariant as invariant14 } from "@dxos/invariant";
|
|
4161
|
+
import { PublicKey as PublicKey11 } from "@dxos/keys";
|
|
4162
|
+
import { log as log15 } from "@dxos/log";
|
|
4163
|
+
import { ConnectionState as ConnectionState4 } from "@dxos/protocols/proto/dxos/mesh/bridge";
|
|
4164
|
+
import { ComplexMap as ComplexMap8 } from "@dxos/util";
|
|
4165
|
+
var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-service.ts";
|
|
4166
|
+
var RtcTransportService = class {
|
|
4167
|
+
constructor(webrtcConfig, iceProvider, _transportFactory = createRtcTransportFactory(webrtcConfig, iceProvider)) {
|
|
4168
|
+
this._transportFactory = _transportFactory;
|
|
4169
|
+
this._openTransports = new ComplexMap8(PublicKey11.hash);
|
|
4170
|
+
}
|
|
4171
|
+
hasOpenTransports() {
|
|
4172
|
+
return this._openTransports.size > 0;
|
|
4173
|
+
}
|
|
4174
|
+
open(request) {
|
|
4175
|
+
const existingTransport = this._openTransports.get(request.proxyId);
|
|
4176
|
+
if (existingTransport) {
|
|
4177
|
+
log15.error("requesting a new transport bridge for an existing proxy", void 0, {
|
|
3875
4178
|
F: __dxlog_file16,
|
|
3876
|
-
L:
|
|
4179
|
+
L: 53,
|
|
3877
4180
|
S: this,
|
|
3878
4181
|
C: (f, a) => f(...a)
|
|
3879
4182
|
});
|
|
3880
|
-
|
|
4183
|
+
void this._safeCloseTransport(existingTransport);
|
|
4184
|
+
this._openTransports.delete(request.proxyId);
|
|
4185
|
+
}
|
|
4186
|
+
return new Stream(({ ready, next, close }) => {
|
|
4187
|
+
const pushNewState = createStateUpdater(next);
|
|
4188
|
+
const transportStream = new Duplex2({
|
|
3881
4189
|
read: () => {
|
|
4190
|
+
const callbacks = [
|
|
4191
|
+
...transportState.writeProcessedCallbacks
|
|
4192
|
+
];
|
|
4193
|
+
transportState.writeProcessedCallbacks.length = 0;
|
|
4194
|
+
callbacks.forEach((cb) => cb());
|
|
3882
4195
|
},
|
|
3883
|
-
write:
|
|
3884
|
-
|
|
3885
|
-
|
|
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
|
-
});
|
|
4196
|
+
write: function(chunk, _, callback) {
|
|
4197
|
+
next({
|
|
4198
|
+
data: {
|
|
4199
|
+
payload: chunk
|
|
3901
4200
|
}
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
callback();
|
|
3905
|
-
}
|
|
4201
|
+
});
|
|
4202
|
+
callback();
|
|
3906
4203
|
}
|
|
3907
4204
|
});
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
4205
|
+
const transport = this._transportFactory.createTransport({
|
|
4206
|
+
initiator: request.initiator,
|
|
4207
|
+
topic: request.topic,
|
|
4208
|
+
ownPeerKey: request.ownPeerKey,
|
|
4209
|
+
remotePeerKey: request.remotePeerKey,
|
|
4210
|
+
stream: transportStream,
|
|
4211
|
+
sendSignal: async (signal) => {
|
|
4212
|
+
next({
|
|
4213
|
+
signal: {
|
|
4214
|
+
payload: signal
|
|
4215
|
+
}
|
|
4216
|
+
});
|
|
4217
|
+
}
|
|
3921
4218
|
});
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
4219
|
+
const transportState = {
|
|
4220
|
+
proxyId: request.proxyId,
|
|
4221
|
+
transport,
|
|
4222
|
+
connectorStream: transportStream,
|
|
4223
|
+
writeProcessedCallbacks: []
|
|
4224
|
+
};
|
|
4225
|
+
pushNewState(ConnectionState4.CONNECTING);
|
|
4226
|
+
transport.connected.on(() => pushNewState(ConnectionState4.CONNECTED));
|
|
4227
|
+
transport.errors.handle(async (err) => {
|
|
4228
|
+
pushNewState(ConnectionState4.CLOSED, err);
|
|
4229
|
+
void this._safeCloseTransport(transportState);
|
|
4230
|
+
close(err);
|
|
4231
|
+
});
|
|
4232
|
+
transport.closed.on(async () => {
|
|
4233
|
+
pushNewState(ConnectionState4.CLOSED);
|
|
4234
|
+
void this._safeCloseTransport(transportState);
|
|
4235
|
+
close();
|
|
4236
|
+
});
|
|
4237
|
+
this._openTransports.set(request.proxyId, transportState);
|
|
4238
|
+
transport.open().catch(async (err) => {
|
|
4239
|
+
pushNewState(ConnectionState4.CLOSED, err);
|
|
4240
|
+
void this._safeCloseTransport(transportState);
|
|
4241
|
+
close(err);
|
|
4242
|
+
});
|
|
4243
|
+
ready();
|
|
4244
|
+
});
|
|
3940
4245
|
}
|
|
3941
|
-
async
|
|
3942
|
-
|
|
4246
|
+
async sendSignal({ proxyId, signal }) {
|
|
4247
|
+
const transport = this._openTransports.get(proxyId);
|
|
4248
|
+
invariant14(transport, void 0, {
|
|
3943
4249
|
F: __dxlog_file16,
|
|
3944
|
-
L:
|
|
4250
|
+
L: 121,
|
|
3945
4251
|
S: this,
|
|
3946
4252
|
A: [
|
|
3947
|
-
"
|
|
3948
|
-
"
|
|
4253
|
+
"transport",
|
|
4254
|
+
""
|
|
3949
4255
|
]
|
|
3950
4256
|
});
|
|
3951
|
-
|
|
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
|
-
}
|
|
4041
|
-
}
|
|
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}`;
|
|
4257
|
+
await transport.transport.onSignal(signal);
|
|
4052
4258
|
}
|
|
4053
|
-
async
|
|
4054
|
-
const
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
}
|
|
4259
|
+
async getDetails({ proxyId }) {
|
|
4260
|
+
const transport = this._openTransports.get(proxyId);
|
|
4261
|
+
invariant14(transport, void 0, {
|
|
4262
|
+
F: __dxlog_file16,
|
|
4263
|
+
L: 128,
|
|
4264
|
+
S: this,
|
|
4265
|
+
A: [
|
|
4266
|
+
"transport",
|
|
4267
|
+
""
|
|
4268
|
+
]
|
|
4269
|
+
});
|
|
4064
4270
|
return {
|
|
4065
|
-
|
|
4066
|
-
bytesReceived: stats.transport.bytesReceived,
|
|
4067
|
-
packetsSent: 0,
|
|
4068
|
-
packetsReceived: 0,
|
|
4069
|
-
rawStats: stats.raw
|
|
4271
|
+
details: await transport.transport.getDetails()
|
|
4070
4272
|
};
|
|
4071
4273
|
}
|
|
4072
|
-
async
|
|
4073
|
-
|
|
4274
|
+
async getStats({ proxyId }) {
|
|
4275
|
+
const transport = this._openTransports.get(proxyId);
|
|
4276
|
+
invariant14(transport, void 0, {
|
|
4074
4277
|
F: __dxlog_file16,
|
|
4075
|
-
L:
|
|
4278
|
+
L: 135,
|
|
4076
4279
|
S: this,
|
|
4077
4280
|
A: [
|
|
4078
|
-
"
|
|
4079
|
-
"
|
|
4281
|
+
"transport",
|
|
4282
|
+
""
|
|
4080
4283
|
]
|
|
4081
4284
|
});
|
|
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
|
-
}
|
|
4092
4285
|
return {
|
|
4093
|
-
transport
|
|
4094
|
-
selectedCandidatePair,
|
|
4095
|
-
remoteCandidate,
|
|
4096
|
-
raw: Object.fromEntries(stats)
|
|
4286
|
+
stats: await transport.transport.getStats()
|
|
4097
4287
|
};
|
|
4098
4288
|
}
|
|
4099
|
-
async
|
|
4100
|
-
this.
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
this.closed = new Event11();
|
|
4117
|
-
this.connected = new Event11();
|
|
4118
|
-
this.errors = new ErrorStream7();
|
|
4119
|
-
}
|
|
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.");
|
|
4289
|
+
async sendData({ proxyId, payload }) {
|
|
4290
|
+
const transport = this._openTransports.get(proxyId);
|
|
4291
|
+
invariant14(transport, void 0, {
|
|
4292
|
+
F: __dxlog_file16,
|
|
4293
|
+
L: 142,
|
|
4294
|
+
S: this,
|
|
4295
|
+
A: [
|
|
4296
|
+
"transport",
|
|
4297
|
+
""
|
|
4298
|
+
]
|
|
4299
|
+
});
|
|
4300
|
+
const bufferHasSpace = transport.connectorStream.push(payload);
|
|
4301
|
+
if (!bufferHasSpace) {
|
|
4302
|
+
await new Promise((resolve) => {
|
|
4303
|
+
transport.writeProcessedCallbacks.push(resolve);
|
|
4304
|
+
});
|
|
4305
|
+
}
|
|
4129
4306
|
}
|
|
4130
|
-
async
|
|
4131
|
-
|
|
4307
|
+
async close({ proxyId }) {
|
|
4308
|
+
const transport = this._openTransports.get(proxyId);
|
|
4309
|
+
if (!transport) {
|
|
4310
|
+
return;
|
|
4311
|
+
}
|
|
4312
|
+
this._openTransports.delete(proxyId);
|
|
4313
|
+
await this._safeCloseTransport(transport);
|
|
4132
4314
|
}
|
|
4133
|
-
async
|
|
4134
|
-
|
|
4315
|
+
async _safeCloseTransport(transport) {
|
|
4316
|
+
if (this._openTransports.get(transport.proxyId) === transport) {
|
|
4317
|
+
this._openTransports.delete(transport.proxyId);
|
|
4318
|
+
}
|
|
4319
|
+
transport.writeProcessedCallbacks.forEach((cb) => cb());
|
|
4320
|
+
try {
|
|
4321
|
+
await transport.transport.close();
|
|
4322
|
+
} catch (error) {
|
|
4323
|
+
log15.warn("transport close error", {
|
|
4324
|
+
message: error?.message
|
|
4325
|
+
}, {
|
|
4326
|
+
F: __dxlog_file16,
|
|
4327
|
+
L: 172,
|
|
4328
|
+
S: this,
|
|
4329
|
+
C: (f, a) => f(...a)
|
|
4330
|
+
});
|
|
4331
|
+
}
|
|
4332
|
+
try {
|
|
4333
|
+
transport.connectorStream.end();
|
|
4334
|
+
} catch (error) {
|
|
4335
|
+
log15.warn("connectorStream close error", {
|
|
4336
|
+
message: error?.message
|
|
4337
|
+
}, {
|
|
4338
|
+
F: __dxlog_file16,
|
|
4339
|
+
L: 177,
|
|
4340
|
+
S: this,
|
|
4341
|
+
C: (f, a) => f(...a)
|
|
4342
|
+
});
|
|
4343
|
+
}
|
|
4344
|
+
log15("closed", void 0, {
|
|
4345
|
+
F: __dxlog_file16,
|
|
4346
|
+
L: 179,
|
|
4347
|
+
S: this,
|
|
4348
|
+
C: (f, a) => f(...a)
|
|
4349
|
+
});
|
|
4135
4350
|
}
|
|
4136
4351
|
};
|
|
4352
|
+
var createStateUpdater = (next) => {
|
|
4353
|
+
return (state, err) => {
|
|
4354
|
+
next({
|
|
4355
|
+
connection: {
|
|
4356
|
+
state,
|
|
4357
|
+
...err ? {
|
|
4358
|
+
error: err.message
|
|
4359
|
+
} : void 0
|
|
4360
|
+
}
|
|
4361
|
+
});
|
|
4362
|
+
};
|
|
4363
|
+
};
|
|
4137
4364
|
|
|
4138
4365
|
// packages/core/mesh/network-manager/src/wire-protocol.ts
|
|
4139
4366
|
import { Teleport } from "@dxos/teleport";
|
|
@@ -4160,7 +4387,6 @@ var createTeleportProtocolFactory = (onConnection, defaultParams) => {
|
|
|
4160
4387
|
};
|
|
4161
4388
|
|
|
4162
4389
|
export {
|
|
4163
|
-
process,
|
|
4164
4390
|
ConnectionState,
|
|
4165
4391
|
Connection,
|
|
4166
4392
|
createIceProvider,
|
|
@@ -4178,15 +4404,10 @@ export {
|
|
|
4178
4404
|
MemoryTransportFactory,
|
|
4179
4405
|
MemoryTransport,
|
|
4180
4406
|
TransportKind,
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
SimplePeerTransportProxyFactory,
|
|
4186
|
-
createLibDataChannelTransportFactory,
|
|
4187
|
-
LibDataChannelTransport,
|
|
4188
|
-
TcpTransportFactory,
|
|
4189
|
-
TcpTransport,
|
|
4407
|
+
createRtcTransportFactory,
|
|
4408
|
+
RtcTransportProxy,
|
|
4409
|
+
RtcTransportProxyFactory,
|
|
4410
|
+
RtcTransportService,
|
|
4190
4411
|
createTeleportProtocolFactory
|
|
4191
4412
|
};
|
|
4192
|
-
//# sourceMappingURL=chunk-
|
|
4413
|
+
//# sourceMappingURL=chunk-UEVA7BFW.mjs.map
|