@dxos/network-manager 0.6.12 → 0.6.13-main.041e8aa
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-GW3YM55A.mjs +14 -0
- package/dist/lib/browser/chunk-GW3YM55A.mjs.map +7 -0
- package/dist/lib/browser/{chunk-XYSYUN63.mjs → chunk-MKIVP7G3.mjs} +1249 -1065
- package/dist/lib/browser/chunk-MKIVP7G3.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +10 -19
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +22 -32
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/transport/tcp/index.mjs +39 -0
- package/dist/lib/browser/transport/tcp/index.mjs.map +7 -0
- package/dist/lib/node/{chunk-4YAYC7WN.cjs → chunk-D6P7ACEM.cjs} +1262 -1205
- package/dist/lib/node/chunk-D6P7ACEM.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 +24 -34
- 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-22DA2US6.mjs +4373 -0
- package/dist/lib/node-esm/chunk-22DA2US6.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 +279 -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/swarm.d.ts +1 -1
- package/dist/types/src/testing/test-builder.d.ts +2 -2
- package/dist/types/src/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/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 +55 -30
- 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 +5 -5
- package/src/swarm/swarm.test.ts +10 -12
- package/src/swarm/swarm.ts +1 -1
- package/src/testing/test-builder.ts +13 -29
- package/src/testing/test-wire-protocol.ts +1 -4
- package/src/tests/basic-test-suite.ts +34 -33
- 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 +9 -9
- 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 +198 -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,7 @@
|
|
|
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
2
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
process
|
|
14
|
-
} from "@dxos/node-std/inject-globals";
|
|
3
|
+
Buffer
|
|
4
|
+
} from "./chunk-GW3YM55A.mjs";
|
|
15
5
|
|
|
16
6
|
// packages/core/mesh/network-manager/src/swarm/connection.ts
|
|
17
7
|
import { DeferredTask, Event, sleep, scheduleTask, scheduleTaskInterval, synchronized, Trigger } from "@dxos/async";
|
|
@@ -20,7 +10,7 @@ import { ErrorStream } from "@dxos/debug";
|
|
|
20
10
|
import { invariant } from "@dxos/invariant";
|
|
21
11
|
import { PublicKey } from "@dxos/keys";
|
|
22
12
|
import { log, logInfo } from "@dxos/log";
|
|
23
|
-
import { CancelledError, ProtocolError, ConnectionResetError, ConnectivityError, TimeoutError,
|
|
13
|
+
import { CancelledError, ProtocolError, ConnectionResetError, ConnectivityError, TimeoutError, trace } from "@dxos/protocols";
|
|
24
14
|
function _ts_decorate(decorators, target, key, desc) {
|
|
25
15
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
26
16
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -56,11 +46,11 @@ var Connection = class {
|
|
|
56
46
|
this._callbacks = _callbacks;
|
|
57
47
|
this._ctx = new Context(void 0, {
|
|
58
48
|
F: __dxlog_file,
|
|
59
|
-
L:
|
|
49
|
+
L: 100
|
|
60
50
|
});
|
|
61
51
|
this.connectedTimeoutContext = new Context(void 0, {
|
|
62
52
|
F: __dxlog_file,
|
|
63
|
-
L:
|
|
53
|
+
L: 101
|
|
64
54
|
});
|
|
65
55
|
this._protocolClosed = new Trigger();
|
|
66
56
|
this._transportClosed = new Trigger();
|
|
@@ -83,7 +73,7 @@ var Connection = class {
|
|
|
83
73
|
initiator: this.initiator
|
|
84
74
|
}, {
|
|
85
75
|
F: __dxlog_file,
|
|
86
|
-
L:
|
|
76
|
+
L: 137,
|
|
87
77
|
S: this,
|
|
88
78
|
C: (f, a) => f(...a)
|
|
89
79
|
});
|
|
@@ -106,7 +96,7 @@ var Connection = class {
|
|
|
106
96
|
async openConnection() {
|
|
107
97
|
invariant(this._state === "INITIAL", "Invalid state.", {
|
|
108
98
|
F: __dxlog_file,
|
|
109
|
-
L:
|
|
99
|
+
L: 167,
|
|
110
100
|
S: this,
|
|
111
101
|
A: [
|
|
112
102
|
"this._state === ConnectionState.INITIAL",
|
|
@@ -117,7 +107,7 @@ var Connection = class {
|
|
|
117
107
|
id: this._instanceId
|
|
118
108
|
}), {
|
|
119
109
|
F: __dxlog_file,
|
|
120
|
-
L:
|
|
110
|
+
L: 168,
|
|
121
111
|
S: this,
|
|
122
112
|
C: (f, a) => f(...a)
|
|
123
113
|
});
|
|
@@ -129,7 +119,7 @@ var Connection = class {
|
|
|
129
119
|
initiator: this.initiator
|
|
130
120
|
}, {
|
|
131
121
|
F: __dxlog_file,
|
|
132
|
-
L:
|
|
122
|
+
L: 169,
|
|
133
123
|
S: this,
|
|
134
124
|
C: (f, a) => f(...a)
|
|
135
125
|
});
|
|
@@ -140,7 +130,7 @@ var Connection = class {
|
|
|
140
130
|
this._protocol.stream.on("close", () => {
|
|
141
131
|
log("protocol stream closed", void 0, {
|
|
142
132
|
F: __dxlog_file,
|
|
143
|
-
L:
|
|
133
|
+
L: 186,
|
|
144
134
|
S: this,
|
|
145
135
|
C: (f, a) => f(...a)
|
|
146
136
|
});
|
|
@@ -150,7 +140,7 @@ var Connection = class {
|
|
|
150
140
|
scheduleTask(this.connectedTimeoutContext, async () => {
|
|
151
141
|
log.info(`timeout waiting ${TRANSPORT_CONNECTION_TIMEOUT / 1e3}s for transport to connect, aborting`, void 0, {
|
|
152
142
|
F: __dxlog_file,
|
|
153
|
-
L:
|
|
143
|
+
L: 194,
|
|
154
144
|
S: this,
|
|
155
145
|
C: (f, a) => f(...a)
|
|
156
146
|
});
|
|
@@ -158,7 +148,7 @@ var Connection = class {
|
|
|
158
148
|
}, TRANSPORT_CONNECTION_TIMEOUT);
|
|
159
149
|
invariant(!this._transport, void 0, {
|
|
160
150
|
F: __dxlog_file,
|
|
161
|
-
L:
|
|
151
|
+
L: 202,
|
|
162
152
|
S: this,
|
|
163
153
|
A: [
|
|
164
154
|
"!this._transport",
|
|
@@ -166,12 +156,14 @@ var Connection = class {
|
|
|
166
156
|
]
|
|
167
157
|
});
|
|
168
158
|
this._transport = this._transportFactory.createTransport({
|
|
159
|
+
ownPeerKey: this.localInfo.peerKey,
|
|
160
|
+
remotePeerKey: this.remoteInfo.peerKey,
|
|
161
|
+
topic: this.topic.toHex(),
|
|
169
162
|
initiator: this.initiator,
|
|
170
163
|
stream: this._protocol.stream,
|
|
171
164
|
sendSignal: async (signal) => this._sendSignal(signal),
|
|
172
165
|
sessionId: this.sessionId
|
|
173
166
|
});
|
|
174
|
-
await this._transport.open();
|
|
175
167
|
this._transport.connected.once(async () => {
|
|
176
168
|
this._changeState("CONNECTED");
|
|
177
169
|
await this.connectedTimeoutContext.dispose();
|
|
@@ -217,21 +209,13 @@ var Connection = class {
|
|
|
217
209
|
C: (f, a) => f(...a)
|
|
218
210
|
});
|
|
219
211
|
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
|
-
});
|
|
229
212
|
}
|
|
230
213
|
if (this._state !== "CLOSED" && this._state !== "CLOSING") {
|
|
231
214
|
await this.connectedTimeoutContext.dispose();
|
|
232
215
|
this.errors.raise(err);
|
|
233
216
|
}
|
|
234
217
|
});
|
|
218
|
+
await this._transport.open();
|
|
235
219
|
for (const signal of this._incomingSignalBuffer) {
|
|
236
220
|
void this._transport.onSignal(signal);
|
|
237
221
|
}
|
|
@@ -598,15 +582,20 @@ var createIceProvider = (iceProviders) => {
|
|
|
598
582
|
}
|
|
599
583
|
cachedIceServers = (await Promise.all(iceProviders.map(({ urls }) => asyncTimeout(fetch(urls, {
|
|
600
584
|
method: "GET"
|
|
601
|
-
}), 1e4).then((response) => response.json()).catch((err) =>
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
585
|
+
}), 1e4).then((response) => response.json()).catch((err) => {
|
|
586
|
+
const isDev = typeof window !== "undefined" && window.location.href.includes("localhost");
|
|
587
|
+
if (!isDev) {
|
|
588
|
+
log2.error("Failed to fetch ICE servers from provider", {
|
|
589
|
+
urls,
|
|
590
|
+
err
|
|
591
|
+
}, {
|
|
592
|
+
F: __dxlog_file2,
|
|
593
|
+
L: 30,
|
|
594
|
+
S: void 0,
|
|
595
|
+
C: (f, a) => f(...a)
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
})))).filter(isNotNullOrUndefined).map(({ iceServers }) => iceServers).flat();
|
|
610
599
|
return cachedIceServers;
|
|
611
600
|
}
|
|
612
601
|
};
|
|
@@ -2226,52 +2215,37 @@ var SwarmNetworkManager = class {
|
|
|
2226
2215
|
/**
|
|
2227
2216
|
* Join the swarm.
|
|
2228
2217
|
*/
|
|
2229
|
-
async joinSwarm({ topic,
|
|
2218
|
+
async joinSwarm({ topic, topology, protocolProvider: protocol, label }) {
|
|
2230
2219
|
invariant6(PublicKey8.isPublicKey(topic), void 0, {
|
|
2231
2220
|
F: __dxlog_file8,
|
|
2232
|
-
L:
|
|
2221
|
+
L: 160,
|
|
2233
2222
|
S: this,
|
|
2234
2223
|
A: [
|
|
2235
2224
|
"PublicKey.isPublicKey(topic)",
|
|
2236
2225
|
""
|
|
2237
2226
|
]
|
|
2238
2227
|
});
|
|
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, {
|
|
2228
|
+
invariant6(topology, void 0, {
|
|
2255
2229
|
F: __dxlog_file8,
|
|
2256
|
-
L:
|
|
2230
|
+
L: 161,
|
|
2257
2231
|
S: this,
|
|
2258
2232
|
A: [
|
|
2259
|
-
"
|
|
2233
|
+
"topology",
|
|
2260
2234
|
""
|
|
2261
2235
|
]
|
|
2262
2236
|
});
|
|
2263
|
-
invariant6(
|
|
2237
|
+
invariant6(this._peerInfo, void 0, {
|
|
2264
2238
|
F: __dxlog_file8,
|
|
2265
|
-
L:
|
|
2239
|
+
L: 162,
|
|
2266
2240
|
S: this,
|
|
2267
2241
|
A: [
|
|
2268
|
-
"
|
|
2242
|
+
"this._peerInfo",
|
|
2269
2243
|
""
|
|
2270
2244
|
]
|
|
2271
2245
|
});
|
|
2272
2246
|
invariant6(typeof protocol === "function", void 0, {
|
|
2273
2247
|
F: __dxlog_file8,
|
|
2274
|
-
L:
|
|
2248
|
+
L: 163,
|
|
2275
2249
|
S: this,
|
|
2276
2250
|
A: [
|
|
2277
2251
|
"typeof protocol === 'function'",
|
|
@@ -2283,21 +2257,21 @@ var SwarmNetworkManager = class {
|
|
|
2283
2257
|
}
|
|
2284
2258
|
log8("joining", {
|
|
2285
2259
|
topic: PublicKey8.from(topic),
|
|
2286
|
-
peerInfo,
|
|
2260
|
+
peerInfo: this._peerInfo,
|
|
2287
2261
|
topology: topology.toString()
|
|
2288
2262
|
}, {
|
|
2289
2263
|
F: __dxlog_file8,
|
|
2290
|
-
L:
|
|
2264
|
+
L: 168,
|
|
2291
2265
|
S: this,
|
|
2292
2266
|
C: (f, a) => f(...a)
|
|
2293
2267
|
});
|
|
2294
|
-
const swarm = new Swarm(topic,
|
|
2268
|
+
const swarm = new Swarm(topic, this._peerInfo, topology, protocol, this._messenger, this._transportFactory, label, this._connectionLimiter);
|
|
2295
2269
|
swarm.errors.handle((error) => {
|
|
2296
2270
|
log8("swarm error", {
|
|
2297
2271
|
error
|
|
2298
2272
|
}, {
|
|
2299
2273
|
F: __dxlog_file8,
|
|
2300
|
-
L:
|
|
2274
|
+
L: 181,
|
|
2301
2275
|
S: this,
|
|
2302
2276
|
C: (f, a) => f(...a)
|
|
2303
2277
|
});
|
|
@@ -2307,10 +2281,10 @@ var SwarmNetworkManager = class {
|
|
|
2307
2281
|
await swarm.open();
|
|
2308
2282
|
this._signalConnection.join({
|
|
2309
2283
|
topic,
|
|
2310
|
-
peer:
|
|
2284
|
+
peer: this._peerInfo
|
|
2311
2285
|
}).catch((error) => log8.catch(error, void 0, {
|
|
2312
2286
|
F: __dxlog_file8,
|
|
2313
|
-
L:
|
|
2287
|
+
L: 190,
|
|
2314
2288
|
S: this,
|
|
2315
2289
|
C: (f, a) => f(...a)
|
|
2316
2290
|
}));
|
|
@@ -2321,7 +2295,7 @@ var SwarmNetworkManager = class {
|
|
|
2321
2295
|
count: this._swarms.size
|
|
2322
2296
|
}, {
|
|
2323
2297
|
F: __dxlog_file8,
|
|
2324
|
-
L:
|
|
2298
|
+
L: 194,
|
|
2325
2299
|
S: this,
|
|
2326
2300
|
C: (f, a) => f(...a)
|
|
2327
2301
|
});
|
|
@@ -2340,7 +2314,7 @@ var SwarmNetworkManager = class {
|
|
|
2340
2314
|
topic: PublicKey8.from(topic)
|
|
2341
2315
|
}, {
|
|
2342
2316
|
F: __dxlog_file8,
|
|
2343
|
-
L:
|
|
2317
|
+
L: 211,
|
|
2344
2318
|
S: this,
|
|
2345
2319
|
C: (f, a) => f(...a)
|
|
2346
2320
|
});
|
|
@@ -2361,7 +2335,7 @@ var SwarmNetworkManager = class {
|
|
|
2361
2335
|
count: this._swarms.size
|
|
2362
2336
|
}, {
|
|
2363
2337
|
F: __dxlog_file8,
|
|
2364
|
-
L:
|
|
2338
|
+
L: 225,
|
|
2365
2339
|
S: this,
|
|
2366
2340
|
C: (f, a) => f(...a)
|
|
2367
2341
|
});
|
|
@@ -2630,7 +2604,7 @@ var sortByXorDistance = (keys, reference) => {
|
|
|
2630
2604
|
};
|
|
2631
2605
|
var distXor = (a, b) => {
|
|
2632
2606
|
const maxLength = Math.max(a.length, b.length);
|
|
2633
|
-
const result =
|
|
2607
|
+
const result = Buffer.allocUnsafe(maxLength);
|
|
2634
2608
|
for (let i = 0; i < maxLength; i++) {
|
|
2635
2609
|
result[i] = (a[i] || 0) ^ (b[i] || 0);
|
|
2636
2610
|
}
|
|
@@ -2865,11 +2839,12 @@ var MemoryTransport = class _MemoryTransport {
|
|
|
2865
2839
|
this.errors.raise(err);
|
|
2866
2840
|
});
|
|
2867
2841
|
}
|
|
2842
|
+
return this;
|
|
2868
2843
|
}
|
|
2869
2844
|
async close() {
|
|
2870
2845
|
log11("closing...", void 0, {
|
|
2871
2846
|
F: __dxlog_file12,
|
|
2872
|
-
L:
|
|
2847
|
+
L: 130,
|
|
2873
2848
|
S: this,
|
|
2874
2849
|
C: (f, a) => f(...a)
|
|
2875
2850
|
});
|
|
@@ -2890,17 +2865,18 @@ var MemoryTransport = class _MemoryTransport {
|
|
|
2890
2865
|
this.closed.emit();
|
|
2891
2866
|
log11("closed", void 0, {
|
|
2892
2867
|
F: __dxlog_file12,
|
|
2893
|
-
L:
|
|
2868
|
+
L: 158,
|
|
2894
2869
|
S: this,
|
|
2895
2870
|
C: (f, a) => f(...a)
|
|
2896
2871
|
});
|
|
2872
|
+
return this;
|
|
2897
2873
|
}
|
|
2898
2874
|
async onSignal({ payload }) {
|
|
2899
2875
|
log11("received signal", {
|
|
2900
2876
|
payload
|
|
2901
2877
|
}, {
|
|
2902
2878
|
F: __dxlog_file12,
|
|
2903
|
-
L:
|
|
2879
|
+
L: 163,
|
|
2904
2880
|
S: this,
|
|
2905
2881
|
C: (f, a) => f(...a)
|
|
2906
2882
|
});
|
|
@@ -2936,524 +2912,978 @@ var toError = (err) => err instanceof Error ? err : new Error(String(err));
|
|
|
2936
2912
|
// packages/core/mesh/network-manager/src/transport/transport.ts
|
|
2937
2913
|
var TransportKind;
|
|
2938
2914
|
(function(TransportKind2) {
|
|
2939
|
-
TransportKind2["
|
|
2940
|
-
TransportKind2["
|
|
2941
|
-
TransportKind2["LIBDATACHANNEL"] = "LIBDATACHANNEL";
|
|
2915
|
+
TransportKind2["WEB_RTC"] = "WEB-RTC";
|
|
2916
|
+
TransportKind2["WEB_RTC_PROXY"] = "WEB-RTC_PROXY";
|
|
2942
2917
|
TransportKind2["MEMORY"] = "MEMORY";
|
|
2943
2918
|
TransportKind2["TCP"] = "TCP";
|
|
2944
2919
|
})(TransportKind || (TransportKind = {}));
|
|
2945
2920
|
|
|
2946
|
-
// packages/core/mesh/network-manager/src/transport/
|
|
2947
|
-
import
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2921
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-connection-factory.ts
|
|
2922
|
+
import { Mutex } from "@dxos/async";
|
|
2923
|
+
var BrowserRtcConnectionFactory = class {
|
|
2924
|
+
async initialize() {
|
|
2925
|
+
}
|
|
2926
|
+
async onConnectionDestroyed() {
|
|
2927
|
+
}
|
|
2928
|
+
async createConnection(config) {
|
|
2929
|
+
return new RTCPeerConnection(config);
|
|
2930
|
+
}
|
|
2931
|
+
async initConnection(connection, info) {
|
|
2932
|
+
}
|
|
2933
|
+
};
|
|
2934
|
+
var NodeRtcConnectionFactory = class _NodeRtcConnectionFactory {
|
|
2935
|
+
static {
|
|
2936
|
+
this._createdConnections = 0;
|
|
2937
|
+
}
|
|
2938
|
+
static {
|
|
2939
|
+
this._cleanupMutex = new Mutex();
|
|
2940
|
+
}
|
|
2941
|
+
// This should be inside the function to avoid triggering `eval` in the global scope.
|
|
2942
|
+
// eslint-disable-next-line no-new-func
|
|
2943
|
+
// TODO(burdon): Do imports here?
|
|
2944
|
+
async initialize() {
|
|
2945
|
+
}
|
|
2946
|
+
async onConnectionDestroyed() {
|
|
2947
|
+
return _NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
|
|
2948
|
+
if (--_NodeRtcConnectionFactory._createdConnections === 0) {
|
|
2949
|
+
(await import("#node-datachannel")).cleanup();
|
|
2950
|
+
}
|
|
2951
|
+
});
|
|
2952
|
+
}
|
|
2953
|
+
async createConnection(config) {
|
|
2954
|
+
return _NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
|
|
2955
|
+
const { RTCPeerConnection: RTCPeerConnection1 } = await import("#node-datachannel/polyfill");
|
|
2956
|
+
_NodeRtcConnectionFactory._createdConnections++;
|
|
2957
|
+
return new RTCPeerConnection1(config);
|
|
2958
|
+
});
|
|
2959
|
+
}
|
|
2960
|
+
async initConnection(connection, info) {
|
|
2961
|
+
if (info.initiator) {
|
|
2962
|
+
connection.onnegotiationneeded?.(null);
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2965
|
+
};
|
|
2966
|
+
var getRtcConnectionFactory = () => {
|
|
2967
|
+
return typeof globalThis.RTCPeerConnection === "undefined" ? new NodeRtcConnectionFactory() : new BrowserRtcConnectionFactory();
|
|
2968
|
+
};
|
|
2954
2969
|
|
|
2955
|
-
// packages/core/mesh/network-manager/src/transport/webrtc.ts
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
}
|
|
2960
|
-
}
|
|
2970
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-peer-connection.ts
|
|
2971
|
+
import { synchronized as synchronized5, Trigger as Trigger3, Mutex as Mutex2 } from "@dxos/async";
|
|
2972
|
+
import { invariant as invariant12 } from "@dxos/invariant";
|
|
2973
|
+
import { log as log13, logInfo as logInfo4 } from "@dxos/log";
|
|
2974
|
+
import { ConnectivityError as ConnectivityError3 } from "@dxos/protocols";
|
|
2975
|
+
import { trace as trace4 } from "@dxos/tracing";
|
|
2961
2976
|
|
|
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;
|
|
2977
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-channel.ts
|
|
2978
|
+
import { Duplex } from "@dxos/node-std/stream";
|
|
2979
|
+
import { Event as AsyncEvent } from "@dxos/async";
|
|
2980
|
+
import { Resource } from "@dxos/context";
|
|
2981
|
+
import { ErrorStream as ErrorStream4 } from "@dxos/debug";
|
|
2982
|
+
import { invariant as invariant11 } from "@dxos/invariant";
|
|
2983
|
+
import { log as log12 } from "@dxos/log";
|
|
2984
|
+
import { ConnectivityError as ConnectivityError2 } from "@dxos/protocols";
|
|
2985
|
+
|
|
2986
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-stats.ts
|
|
2987
|
+
var describeSelectedRemoteCandidate = async (connection) => {
|
|
2988
|
+
const stats = connection && await getRtcConnectionStats(connection);
|
|
2989
|
+
const rc = stats?.remoteCandidate;
|
|
2990
|
+
if (!rc) {
|
|
2991
|
+
return "unavailable";
|
|
2980
2992
|
}
|
|
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();
|
|
2993
|
+
if (rc.candidateType === "relay") {
|
|
2994
|
+
return `${rc.ip}:${rc.port} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
|
|
2993
2995
|
}
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
bytesReceived: 0,
|
|
3000
|
-
packetsSent: 0,
|
|
3001
|
-
packetsReceived: 0,
|
|
3002
|
-
rawStats: {}
|
|
3003
|
-
};
|
|
3004
|
-
}
|
|
2996
|
+
return `${rc.ip}:${rc.port} ${rc.candidateType}`;
|
|
2997
|
+
};
|
|
2998
|
+
var createRtcTransportStats = async (connection, topic) => {
|
|
2999
|
+
const stats = connection && await getRtcConnectionStats(connection, topic);
|
|
3000
|
+
if (!stats) {
|
|
3005
3001
|
return {
|
|
3006
|
-
bytesSent:
|
|
3007
|
-
bytesReceived:
|
|
3008
|
-
packetsSent:
|
|
3009
|
-
packetsReceived:
|
|
3010
|
-
rawStats:
|
|
3002
|
+
bytesSent: 0,
|
|
3003
|
+
bytesReceived: 0,
|
|
3004
|
+
packetsSent: 0,
|
|
3005
|
+
packetsReceived: 0,
|
|
3006
|
+
rawStats: {}
|
|
3011
3007
|
};
|
|
3012
3008
|
}
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3009
|
+
return {
|
|
3010
|
+
bytesSent: stats.dataChannel?.bytesSent,
|
|
3011
|
+
bytesReceived: stats.dataChannel?.bytesReceived,
|
|
3012
|
+
packetsSent: 0,
|
|
3013
|
+
packetsReceived: 0,
|
|
3014
|
+
rawStats: stats.raw
|
|
3015
|
+
};
|
|
3016
|
+
};
|
|
3017
|
+
var getRtcConnectionStats = async (connection, channelTopic) => {
|
|
3018
|
+
const stats = await connection.getStats();
|
|
3019
|
+
const statsEntries = Array.from(stats.entries());
|
|
3020
|
+
const transport = statsEntries.find(([_, entry]) => entry.type === "transport")?.[1];
|
|
3021
|
+
const selectedCandidatePair = transport && statsEntries.find(([entryId]) => entryId === transport.selectedCandidatePairId)?.[1];
|
|
3022
|
+
const remoteCandidate = selectedCandidatePair && statsEntries.find(([entryId]) => entryId === selectedCandidatePair.remoteCandidateId)?.[1];
|
|
3023
|
+
const dataChannel = channelTopic && statsEntries.find(([_, entry]) => entry.type === "data-channel" && entry.label === channelTopic)?.[1];
|
|
3024
|
+
return {
|
|
3025
|
+
transport,
|
|
3026
|
+
selectedCandidatePair,
|
|
3027
|
+
dataChannel,
|
|
3028
|
+
remoteCandidate,
|
|
3029
|
+
raw: Object.fromEntries(stats)
|
|
3030
|
+
};
|
|
3031
|
+
};
|
|
3032
|
+
|
|
3033
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-channel.ts
|
|
3034
|
+
var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-channel.ts";
|
|
3035
|
+
var MAX_MESSAGE_SIZE = 64 * 1024;
|
|
3036
|
+
var MAX_BUFFERED_AMOUNT = 64 * 1024;
|
|
3037
|
+
var RtcTransportChannel = class extends Resource {
|
|
3038
|
+
constructor(_connection, _options) {
|
|
3039
|
+
super();
|
|
3040
|
+
this._connection = _connection;
|
|
3041
|
+
this._options = _options;
|
|
3042
|
+
this.closed = new AsyncEvent();
|
|
3043
|
+
this.connected = new AsyncEvent();
|
|
3044
|
+
this.errors = new ErrorStream4();
|
|
3045
|
+
this._streamDataFlushedCallback = null;
|
|
3046
|
+
this._isChannelCreationInProgress = false;
|
|
3035
3047
|
}
|
|
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}`;
|
|
3048
|
+
get isRtcChannelCreationInProgress() {
|
|
3049
|
+
return this._isChannelCreationInProgress;
|
|
3050
|
+
}
|
|
3051
|
+
onConnectionError(error) {
|
|
3052
|
+
if (this.isOpen) {
|
|
3053
|
+
this.errors.raise(error);
|
|
3044
3054
|
}
|
|
3045
|
-
return `${rc.ip}:${rc.port}/${rc.protocol} ${rc.candidateType}`;
|
|
3046
3055
|
}
|
|
3047
|
-
async
|
|
3048
|
-
|
|
3049
|
-
id: this._instanceId
|
|
3050
|
-
}), {
|
|
3056
|
+
async _open() {
|
|
3057
|
+
invariant11(!this._isChannelCreationInProgress, void 0, {
|
|
3051
3058
|
F: __dxlog_file13,
|
|
3052
|
-
L:
|
|
3059
|
+
L: 56,
|
|
3053
3060
|
S: this,
|
|
3054
|
-
|
|
3061
|
+
A: [
|
|
3062
|
+
"!this._isChannelCreationInProgress",
|
|
3063
|
+
""
|
|
3064
|
+
]
|
|
3055
3065
|
});
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3066
|
+
this._isChannelCreationInProgress = true;
|
|
3067
|
+
this._connection.createDataChannel(this._options.topic).then((channel) => {
|
|
3068
|
+
if (this.isOpen) {
|
|
3069
|
+
this._channel = channel;
|
|
3070
|
+
this._initChannel(this._channel);
|
|
3071
|
+
} else {
|
|
3072
|
+
this._safeCloseChannel(channel);
|
|
3073
|
+
}
|
|
3074
|
+
}).catch((err) => {
|
|
3075
|
+
if (this.isOpen) {
|
|
3076
|
+
this.errors.raise(new ConnectivityError2(`Failed to create a channel: ${err?.message ?? "unknown reason."}`));
|
|
3077
|
+
}
|
|
3078
|
+
}).finally(() => {
|
|
3079
|
+
this._isChannelCreationInProgress = false;
|
|
3080
|
+
});
|
|
3081
|
+
}
|
|
3082
|
+
async _close() {
|
|
3083
|
+
if (this._channel) {
|
|
3084
|
+
this._safeCloseChannel(this._channel);
|
|
3085
|
+
this._channel = void 0;
|
|
3086
|
+
this._stream = void 0;
|
|
3087
|
+
}
|
|
3088
|
+
this.closed.emit();
|
|
3089
|
+
log12("closed", void 0, {
|
|
3059
3090
|
F: __dxlog_file13,
|
|
3060
|
-
L:
|
|
3091
|
+
L: 86,
|
|
3061
3092
|
S: this,
|
|
3062
3093
|
C: (f, a) => f(...a)
|
|
3063
3094
|
});
|
|
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
|
|
3095
|
+
}
|
|
3096
|
+
_initChannel(channel) {
|
|
3097
|
+
Object.assign(channel, {
|
|
3098
|
+
onopen: () => {
|
|
3099
|
+
if (!this.isOpen) {
|
|
3100
|
+
log12.warn("channel opened in a closed transport", {
|
|
3101
|
+
topic: this._options.topic
|
|
3118
3102
|
}, {
|
|
3119
3103
|
F: __dxlog_file13,
|
|
3120
|
-
L:
|
|
3104
|
+
L: 93,
|
|
3121
3105
|
S: this,
|
|
3122
3106
|
C: (f, a) => f(...a)
|
|
3123
3107
|
});
|
|
3124
|
-
this.
|
|
3108
|
+
this._safeCloseChannel(channel);
|
|
3109
|
+
return;
|
|
3125
3110
|
}
|
|
3126
|
-
|
|
3127
|
-
log12.info("simple-peer error", err, {
|
|
3111
|
+
log12("onopen", void 0, {
|
|
3128
3112
|
F: __dxlog_file13,
|
|
3129
|
-
L:
|
|
3113
|
+
L: 98,
|
|
3130
3114
|
S: this,
|
|
3131
3115
|
C: (f, a) => f(...a)
|
|
3132
3116
|
});
|
|
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, {
|
|
3117
|
+
const duplex = new Duplex({
|
|
3118
|
+
read: () => {
|
|
3119
|
+
},
|
|
3120
|
+
write: (chunk, encoding, callback) => {
|
|
3121
|
+
return this._handleChannelWrite(chunk, callback);
|
|
3122
|
+
}
|
|
3123
|
+
});
|
|
3124
|
+
duplex.pipe(this._options.stream).pipe(duplex);
|
|
3125
|
+
this._stream = duplex;
|
|
3126
|
+
this.connected.emit();
|
|
3127
|
+
},
|
|
3128
|
+
onclose: async () => {
|
|
3129
|
+
log12("onclose", void 0, {
|
|
3159
3130
|
F: __dxlog_file13,
|
|
3160
|
-
L:
|
|
3131
|
+
L: 111,
|
|
3161
3132
|
S: this,
|
|
3162
3133
|
C: (f, a) => f(...a)
|
|
3163
3134
|
});
|
|
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
|
-
});
|
|
3135
|
+
await this.close();
|
|
3136
|
+
},
|
|
3137
|
+
onmessage: (event) => {
|
|
3138
|
+
if (!this._stream) {
|
|
3139
|
+
log12.warn("ignoring message on a closed channel", void 0, {
|
|
3140
|
+
F: __dxlog_file13,
|
|
3141
|
+
L: 117,
|
|
3142
|
+
S: this,
|
|
3143
|
+
C: (f, a) => f(...a)
|
|
3178
3144
|
});
|
|
3145
|
+
return;
|
|
3179
3146
|
}
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3147
|
+
let data = event.data;
|
|
3148
|
+
if (data instanceof ArrayBuffer) {
|
|
3149
|
+
data = Buffer.from(data);
|
|
3150
|
+
}
|
|
3151
|
+
this._stream.push(data);
|
|
3152
|
+
},
|
|
3153
|
+
onerror: (event) => {
|
|
3154
|
+
if (this.isOpen) {
|
|
3155
|
+
const err = event.error instanceof Error ? event.error : new Error(`Datachannel error: ${event.type}.`);
|
|
3156
|
+
this.errors.raise(err);
|
|
3157
|
+
}
|
|
3158
|
+
},
|
|
3159
|
+
onbufferedamountlow: () => {
|
|
3160
|
+
const cb = this._streamDataFlushedCallback;
|
|
3161
|
+
this._streamDataFlushedCallback = null;
|
|
3162
|
+
cb?.();
|
|
3187
3163
|
}
|
|
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
3164
|
});
|
|
3198
3165
|
}
|
|
3199
|
-
async
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3166
|
+
async _handleChannelWrite(chunk, callback) {
|
|
3167
|
+
if (!this._channel) {
|
|
3168
|
+
log12.warn("writing to a channel after a connection was closed", void 0, {
|
|
3169
|
+
F: __dxlog_file13,
|
|
3170
|
+
L: 145,
|
|
3171
|
+
S: this,
|
|
3172
|
+
C: (f, a) => f(...a)
|
|
3173
|
+
});
|
|
3207
3174
|
return;
|
|
3208
3175
|
}
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
async onSignal(signal) {
|
|
3221
|
-
if (this._closed) {
|
|
3176
|
+
if (chunk.length > MAX_MESSAGE_SIZE) {
|
|
3177
|
+
const error = new Error(`Message too large: ${chunk.length} > ${MAX_MESSAGE_SIZE}.`);
|
|
3178
|
+
this.errors.raise(error);
|
|
3179
|
+
callback();
|
|
3180
|
+
return;
|
|
3181
|
+
}
|
|
3182
|
+
try {
|
|
3183
|
+
this._channel.send(chunk);
|
|
3184
|
+
} catch (err) {
|
|
3185
|
+
this.errors.raise(err);
|
|
3186
|
+
callback();
|
|
3222
3187
|
return;
|
|
3223
3188
|
}
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3189
|
+
if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {
|
|
3190
|
+
if (this._streamDataFlushedCallback !== null) {
|
|
3191
|
+
log12.error("consumer trying to write before we are ready for more data", void 0, {
|
|
3192
|
+
F: __dxlog_file13,
|
|
3193
|
+
L: 166,
|
|
3194
|
+
S: this,
|
|
3195
|
+
C: (f, a) => f(...a)
|
|
3196
|
+
});
|
|
3197
|
+
}
|
|
3198
|
+
this._streamDataFlushedCallback = callback;
|
|
3199
|
+
} else {
|
|
3200
|
+
callback();
|
|
3201
|
+
}
|
|
3227
3202
|
}
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3203
|
+
_safeCloseChannel(channel) {
|
|
3204
|
+
try {
|
|
3205
|
+
channel.close();
|
|
3206
|
+
} catch (error) {
|
|
3207
|
+
log12.catch(error, void 0, {
|
|
3208
|
+
F: __dxlog_file13,
|
|
3209
|
+
L: 178,
|
|
3210
|
+
S: this,
|
|
3211
|
+
C: (f, a) => f(...a)
|
|
3212
|
+
});
|
|
3231
3213
|
}
|
|
3232
3214
|
}
|
|
3215
|
+
onSignal(signal) {
|
|
3216
|
+
return this._connection.onSignal(signal);
|
|
3217
|
+
}
|
|
3218
|
+
async getDetails() {
|
|
3219
|
+
return describeSelectedRemoteCandidate(this._connection.currentConnection);
|
|
3220
|
+
}
|
|
3221
|
+
async getStats() {
|
|
3222
|
+
return createRtcTransportStats(this._connection.currentConnection, this._options.topic);
|
|
3223
|
+
}
|
|
3233
3224
|
};
|
|
3234
|
-
_ts_decorate6([
|
|
3235
|
-
synchronized5
|
|
3236
|
-
], SimplePeerTransport.prototype, "open", null);
|
|
3237
|
-
_ts_decorate6([
|
|
3238
|
-
synchronized5
|
|
3239
|
-
], SimplePeerTransport.prototype, "close", null);
|
|
3240
|
-
_ts_decorate6([
|
|
3241
|
-
synchronized5
|
|
3242
|
-
], SimplePeerTransport.prototype, "onSignal", null);
|
|
3243
3225
|
|
|
3244
|
-
// packages/core/mesh/network-manager/src/transport/
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3226
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/utils.ts
|
|
3227
|
+
var chooseInitiatorPeer = (peer1Key, peer2Key) => peer1Key < peer2Key ? peer1Key : peer2Key;
|
|
3228
|
+
var areSdpEqual = (sdp1, sdp2) => {
|
|
3229
|
+
const sdp1Lines = deduplicatedSdpLines(sdp1);
|
|
3230
|
+
const sdp2Lines = deduplicatedSdpLines(sdp2);
|
|
3231
|
+
if (sdp1Lines.length !== sdp2Lines.length) {
|
|
3232
|
+
return false;
|
|
3233
|
+
}
|
|
3234
|
+
return sdp1Lines.every((line, idx) => line === sdp2Lines[idx]);
|
|
3235
|
+
};
|
|
3236
|
+
var deduplicatedSdpLines = (sdp) => {
|
|
3237
|
+
const deduplicatedLines = [];
|
|
3238
|
+
const seenLines = [];
|
|
3239
|
+
for (const line of sdp.split("\r\n")) {
|
|
3240
|
+
if (line.startsWith("m")) {
|
|
3241
|
+
seenLines.length = 0;
|
|
3242
|
+
}
|
|
3243
|
+
if (seenLines.includes(line)) {
|
|
3244
|
+
continue;
|
|
3245
|
+
}
|
|
3246
|
+
seenLines.push(line);
|
|
3247
|
+
deduplicatedLines.push(line);
|
|
3258
3248
|
}
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3249
|
+
return deduplicatedLines;
|
|
3250
|
+
};
|
|
3251
|
+
|
|
3252
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-peer-connection.ts
|
|
3253
|
+
function _ts_decorate6(decorators, target, key, desc) {
|
|
3254
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3255
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3256
|
+
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;
|
|
3257
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3258
|
+
}
|
|
3259
|
+
var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-peer-connection.ts";
|
|
3260
|
+
var RtcPeerConnection = class {
|
|
3261
|
+
constructor(_factory, _options) {
|
|
3262
|
+
this._factory = _factory;
|
|
3263
|
+
this._options = _options;
|
|
3264
|
+
this._channelCreatedCallbacks = /* @__PURE__ */ new Map();
|
|
3265
|
+
this._transportChannels = /* @__PURE__ */ new Map();
|
|
3266
|
+
this._dataChannels = /* @__PURE__ */ new Map();
|
|
3267
|
+
this._readyForCandidates = new Trigger3();
|
|
3268
|
+
this._offerProcessingMutex = new Mutex2();
|
|
3269
|
+
this._initiator = chooseInitiatorPeer(_options.ownPeerKey, _options.remotePeerKey) === _options.ownPeerKey;
|
|
3270
|
+
}
|
|
3271
|
+
get transportChannelCount() {
|
|
3272
|
+
return this._transportChannels.size;
|
|
3273
|
+
}
|
|
3274
|
+
get currentConnection() {
|
|
3275
|
+
return this._connection;
|
|
3276
|
+
}
|
|
3277
|
+
async createDataChannel(topic) {
|
|
3278
|
+
const connection = await this._openConnection();
|
|
3279
|
+
if (!this._transportChannels.has(topic)) {
|
|
3280
|
+
if (!this._transportChannels.size) {
|
|
3281
|
+
this._lockAndCloseConnection();
|
|
3282
|
+
}
|
|
3283
|
+
throw new Error("Transport closed while connection was being open");
|
|
3284
|
+
}
|
|
3285
|
+
if (this._initiator) {
|
|
3286
|
+
const channel = connection.createDataChannel(topic);
|
|
3287
|
+
this._dataChannels.set(topic, channel);
|
|
3288
|
+
return channel;
|
|
3289
|
+
} else {
|
|
3290
|
+
const existingChannel = this._dataChannels.get(topic);
|
|
3291
|
+
if (existingChannel) {
|
|
3292
|
+
return existingChannel;
|
|
3293
|
+
}
|
|
3294
|
+
log13("waiting for initiator-peer to open a data channel", void 0, {
|
|
3295
|
+
F: __dxlog_file14,
|
|
3296
|
+
L: 90,
|
|
3297
|
+
S: this,
|
|
3298
|
+
C: (f, a) => f(...a)
|
|
3279
3299
|
});
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
next({
|
|
3286
|
-
signal: {
|
|
3287
|
-
payload: signal
|
|
3288
|
-
}
|
|
3289
|
-
});
|
|
3290
|
-
},
|
|
3291
|
-
iceProvider: this._iceProvider
|
|
3300
|
+
return new Promise((resolve, reject) => {
|
|
3301
|
+
this._channelCreatedCallbacks.set(topic, {
|
|
3302
|
+
resolve,
|
|
3303
|
+
reject
|
|
3304
|
+
});
|
|
3292
3305
|
});
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
createTransportChannel(options) {
|
|
3309
|
+
const channel = new RtcTransportChannel(this, options);
|
|
3310
|
+
this._transportChannels.set(options.topic, channel);
|
|
3311
|
+
channel.closed.on(() => {
|
|
3312
|
+
this._transportChannels.delete(options.topic);
|
|
3313
|
+
if (this._transportChannels.size === 0) {
|
|
3314
|
+
this._lockAndCloseConnection();
|
|
3315
|
+
}
|
|
3316
|
+
});
|
|
3317
|
+
return channel;
|
|
3318
|
+
}
|
|
3319
|
+
async _openConnection() {
|
|
3320
|
+
if (this._connection) {
|
|
3321
|
+
return this._connection;
|
|
3322
|
+
}
|
|
3323
|
+
log13("initializing connection...", () => ({
|
|
3324
|
+
remotePeer: this._options.remotePeerKey
|
|
3325
|
+
}), {
|
|
3326
|
+
F: __dxlog_file14,
|
|
3327
|
+
L: 115,
|
|
3328
|
+
S: this,
|
|
3329
|
+
C: (f, a) => f(...a)
|
|
3330
|
+
});
|
|
3331
|
+
const config = await this._loadConnectionConfig();
|
|
3332
|
+
const connection = await this._factory.createConnection(config);
|
|
3333
|
+
const iceCandidateErrors = [];
|
|
3334
|
+
Object.assign(connection, {
|
|
3335
|
+
onnegotiationneeded: async () => {
|
|
3336
|
+
invariant12(this._initiator, void 0, {
|
|
3337
|
+
F: __dxlog_file14,
|
|
3338
|
+
L: 130,
|
|
3339
|
+
S: this,
|
|
3340
|
+
A: [
|
|
3341
|
+
"this._initiator",
|
|
3342
|
+
""
|
|
3343
|
+
]
|
|
3344
|
+
});
|
|
3345
|
+
if (connection !== this._connection) {
|
|
3346
|
+
this._onConnectionCallbackAfterClose("onnegotiationneeded", connection);
|
|
3347
|
+
return;
|
|
3297
3348
|
}
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
}
|
|
3349
|
+
log13("onnegotiationneeded", void 0, {
|
|
3350
|
+
F: __dxlog_file14,
|
|
3351
|
+
L: 137,
|
|
3352
|
+
S: this,
|
|
3353
|
+
C: (f, a) => f(...a)
|
|
3304
3354
|
});
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
connection
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3355
|
+
try {
|
|
3356
|
+
const offer = await connection.createOffer();
|
|
3357
|
+
await connection.setLocalDescription(offer);
|
|
3358
|
+
await this._sendDescription(connection, offer);
|
|
3359
|
+
} catch (err) {
|
|
3360
|
+
this._lockAndAbort(connection, err);
|
|
3361
|
+
}
|
|
3362
|
+
},
|
|
3363
|
+
// When ICE candidate identified (should be sent to remote peer) and when ICE gathering finalized.
|
|
3364
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidate_event
|
|
3365
|
+
onicecandidate: async (event) => {
|
|
3366
|
+
if (connection !== this._connection) {
|
|
3367
|
+
this._onConnectionCallbackAfterClose("onicecandidate", connection);
|
|
3368
|
+
return;
|
|
3369
|
+
}
|
|
3370
|
+
if (event.candidate) {
|
|
3371
|
+
log13("onicecandidate", {
|
|
3372
|
+
candidate: event.candidate.candidate
|
|
3373
|
+
}, {
|
|
3374
|
+
F: __dxlog_file14,
|
|
3375
|
+
L: 156,
|
|
3376
|
+
S: this,
|
|
3377
|
+
C: (f, a) => f(...a)
|
|
3378
|
+
});
|
|
3379
|
+
await this._sendIceCandidate(event.candidate);
|
|
3380
|
+
} else {
|
|
3381
|
+
log13("onicecandidate gathering complete", void 0, {
|
|
3382
|
+
F: __dxlog_file14,
|
|
3383
|
+
L: 159,
|
|
3384
|
+
S: this,
|
|
3385
|
+
C: (f, a) => f(...a)
|
|
3386
|
+
});
|
|
3387
|
+
}
|
|
3388
|
+
},
|
|
3389
|
+
// When error occurs while performing ICE negotiations through a STUN or TURN server.
|
|
3390
|
+
// It's ok for some candidates to fail if a working pair is eventually found.
|
|
3391
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidateerror_event
|
|
3392
|
+
onicecandidateerror: (event) => {
|
|
3393
|
+
const { url, errorCode, errorText } = event;
|
|
3394
|
+
iceCandidateErrors.push({
|
|
3395
|
+
url,
|
|
3396
|
+
errorCode,
|
|
3397
|
+
errorText
|
|
3312
3398
|
});
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3399
|
+
},
|
|
3400
|
+
// When possible error during ICE gathering.
|
|
3401
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceconnectionstatechange_event
|
|
3402
|
+
oniceconnectionstatechange: () => {
|
|
3403
|
+
if (connection !== this._connection) {
|
|
3404
|
+
this._onConnectionCallbackAfterClose("oniceconnectionstatechange", connection);
|
|
3405
|
+
return;
|
|
3406
|
+
}
|
|
3407
|
+
log13("oniceconnectionstatechange", {
|
|
3408
|
+
state: connection.iceConnectionState
|
|
3409
|
+
}, {
|
|
3410
|
+
F: __dxlog_file14,
|
|
3411
|
+
L: 179,
|
|
3412
|
+
S: this,
|
|
3413
|
+
C: (f, a) => f(...a)
|
|
3414
|
+
});
|
|
3415
|
+
if (connection.iceConnectionState === "failed") {
|
|
3416
|
+
this._lockAndAbort(connection, createIceFailureError(iceCandidateErrors));
|
|
3417
|
+
}
|
|
3418
|
+
},
|
|
3419
|
+
// When new track (or channel) is added.
|
|
3420
|
+
// State: { new, connecting, connected, disconnected, failed, closed }
|
|
3421
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionstatechange_event
|
|
3422
|
+
onconnectionstatechange: () => {
|
|
3423
|
+
if (connection !== this._connection) {
|
|
3424
|
+
if (connection.connectionState !== "closed" && connection.connectionState !== "failed") {
|
|
3425
|
+
this._onConnectionCallbackAfterClose("onconnectionstatechange", connection);
|
|
3319
3426
|
}
|
|
3427
|
+
return;
|
|
3428
|
+
}
|
|
3429
|
+
log13("onconnectionstatechange", {
|
|
3430
|
+
state: connection.connectionState
|
|
3431
|
+
}, {
|
|
3432
|
+
F: __dxlog_file14,
|
|
3433
|
+
L: 196,
|
|
3434
|
+
S: this,
|
|
3435
|
+
C: (f, a) => f(...a)
|
|
3320
3436
|
});
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3437
|
+
if (connection.connectionState === "failed") {
|
|
3438
|
+
this._lockAndAbort(connection, new Error("Connection failed."));
|
|
3439
|
+
}
|
|
3440
|
+
},
|
|
3441
|
+
onsignalingstatechange: () => {
|
|
3442
|
+
log13("onsignalingstatechange", {
|
|
3443
|
+
state: connection.signalingState
|
|
3444
|
+
}, {
|
|
3445
|
+
F: __dxlog_file14,
|
|
3446
|
+
L: 203,
|
|
3447
|
+
S: this,
|
|
3448
|
+
C: (f, a) => f(...a)
|
|
3449
|
+
});
|
|
3450
|
+
},
|
|
3451
|
+
// When channel is added to connection.
|
|
3452
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/datachannel_event
|
|
3453
|
+
ondatachannel: (event) => {
|
|
3454
|
+
invariant12(!this._initiator, "Initiator is expected to create data channels.", {
|
|
3455
|
+
F: __dxlog_file14,
|
|
3456
|
+
L: 209,
|
|
3457
|
+
S: this,
|
|
3458
|
+
A: [
|
|
3459
|
+
"!this._initiator",
|
|
3460
|
+
"'Initiator is expected to create data channels.'"
|
|
3461
|
+
]
|
|
3462
|
+
});
|
|
3463
|
+
if (connection !== this._connection) {
|
|
3464
|
+
this._onConnectionCallbackAfterClose("ondatachannel", connection);
|
|
3465
|
+
return;
|
|
3466
|
+
}
|
|
3467
|
+
log13("ondatachannel", {
|
|
3468
|
+
label: event.channel.label
|
|
3469
|
+
}, {
|
|
3470
|
+
F: __dxlog_file14,
|
|
3471
|
+
L: 216,
|
|
3472
|
+
S: this,
|
|
3473
|
+
C: (f, a) => f(...a)
|
|
3474
|
+
});
|
|
3475
|
+
this._dataChannels.set(event.channel.label, event.channel);
|
|
3476
|
+
const pendingCallback = this._channelCreatedCallbacks.get(event.channel.label);
|
|
3477
|
+
if (pendingCallback) {
|
|
3478
|
+
this._channelCreatedCallbacks.delete(event.channel.label);
|
|
3479
|
+
pendingCallback.resolve(event.channel);
|
|
3480
|
+
}
|
|
3481
|
+
}
|
|
3331
3482
|
});
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
F: __dxlog_file14,
|
|
3337
|
-
L: 124,
|
|
3338
|
-
S: this,
|
|
3339
|
-
A: [
|
|
3340
|
-
"this.transports.has(proxyId)",
|
|
3341
|
-
""
|
|
3342
|
-
]
|
|
3483
|
+
this._connection = connection;
|
|
3484
|
+
this._readyForCandidates.reset();
|
|
3485
|
+
await this._factory.initConnection(connection, {
|
|
3486
|
+
initiator: this._initiator
|
|
3343
3487
|
});
|
|
3344
|
-
|
|
3488
|
+
return this._connection;
|
|
3345
3489
|
}
|
|
3346
|
-
|
|
3347
|
-
|
|
3490
|
+
_lockAndAbort(connection, error) {
|
|
3491
|
+
this._abortConnection(connection, error);
|
|
3492
|
+
}
|
|
3493
|
+
_abortConnection(connection, error) {
|
|
3494
|
+
if (connection !== this._connection) {
|
|
3495
|
+
log13.error("attempted to abort an inactive connection", {
|
|
3496
|
+
error
|
|
3497
|
+
}, {
|
|
3498
|
+
F: __dxlog_file14,
|
|
3499
|
+
L: 241,
|
|
3500
|
+
S: this,
|
|
3501
|
+
C: (f, a) => f(...a)
|
|
3502
|
+
});
|
|
3503
|
+
this._safeCloseConnection(connection);
|
|
3504
|
+
return;
|
|
3505
|
+
}
|
|
3506
|
+
for (const [topic, pendingCallback] of this._channelCreatedCallbacks.entries()) {
|
|
3507
|
+
pendingCallback.reject(error);
|
|
3508
|
+
this._transportChannels.delete(topic);
|
|
3509
|
+
}
|
|
3510
|
+
this._channelCreatedCallbacks.clear();
|
|
3511
|
+
for (const channel of this._transportChannels.values()) {
|
|
3512
|
+
channel.onConnectionError(error);
|
|
3513
|
+
}
|
|
3514
|
+
this._transportChannels.clear();
|
|
3515
|
+
this._safeCloseConnection();
|
|
3516
|
+
log13("connection aborted", {
|
|
3517
|
+
reason: error.message
|
|
3518
|
+
}, {
|
|
3348
3519
|
F: __dxlog_file14,
|
|
3349
|
-
L:
|
|
3520
|
+
L: 255,
|
|
3350
3521
|
S: this,
|
|
3351
|
-
|
|
3352
|
-
"this.transports.has(proxyId)",
|
|
3353
|
-
""
|
|
3354
|
-
]
|
|
3522
|
+
C: (f, a) => f(...a)
|
|
3355
3523
|
});
|
|
3356
|
-
return {
|
|
3357
|
-
details: await this.transports.get(proxyId).transport.getDetails()
|
|
3358
|
-
};
|
|
3359
3524
|
}
|
|
3360
|
-
|
|
3361
|
-
invariant12(this.
|
|
3525
|
+
_lockAndCloseConnection() {
|
|
3526
|
+
invariant12(this._transportChannels.size === 0, void 0, {
|
|
3362
3527
|
F: __dxlog_file14,
|
|
3363
|
-
L:
|
|
3528
|
+
L: 260,
|
|
3364
3529
|
S: this,
|
|
3365
3530
|
A: [
|
|
3366
|
-
"this.
|
|
3531
|
+
"this._transportChannels.size === 0",
|
|
3367
3532
|
""
|
|
3368
3533
|
]
|
|
3369
3534
|
});
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3535
|
+
if (this._connection) {
|
|
3536
|
+
this._safeCloseConnection();
|
|
3537
|
+
log13("connection closed", void 0, {
|
|
3538
|
+
F: __dxlog_file14,
|
|
3539
|
+
L: 263,
|
|
3540
|
+
S: this,
|
|
3541
|
+
C: (f, a) => f(...a)
|
|
3542
|
+
});
|
|
3543
|
+
}
|
|
3373
3544
|
}
|
|
3374
|
-
async
|
|
3375
|
-
|
|
3376
|
-
|
|
3545
|
+
async onSignal(signal) {
|
|
3546
|
+
const connection = this._connection;
|
|
3547
|
+
if (!connection) {
|
|
3548
|
+
log13.warn("a signal ignored because the connection was closed", {
|
|
3549
|
+
type: signal.payload.data.type
|
|
3550
|
+
}, {
|
|
3377
3551
|
F: __dxlog_file14,
|
|
3378
|
-
L:
|
|
3552
|
+
L: 271,
|
|
3379
3553
|
S: this,
|
|
3380
3554
|
C: (f, a) => f(...a)
|
|
3381
3555
|
});
|
|
3556
|
+
return;
|
|
3557
|
+
}
|
|
3558
|
+
const data = signal.payload.data;
|
|
3559
|
+
switch (data.type) {
|
|
3560
|
+
case "offer": {
|
|
3561
|
+
await this._offerProcessingMutex.executeSynchronized(async () => {
|
|
3562
|
+
if (isRemoteDescriptionSet(connection, data)) {
|
|
3563
|
+
return;
|
|
3564
|
+
}
|
|
3565
|
+
if (connection.connectionState !== "new") {
|
|
3566
|
+
this._abortConnection(connection, new Error(`Received an offer in ${connection.connectionState}.`));
|
|
3567
|
+
return;
|
|
3568
|
+
}
|
|
3569
|
+
try {
|
|
3570
|
+
await connection.setRemoteDescription({
|
|
3571
|
+
type: data.type,
|
|
3572
|
+
sdp: data.sdp
|
|
3573
|
+
});
|
|
3574
|
+
const answer = await connection.createAnswer();
|
|
3575
|
+
await connection.setLocalDescription(answer);
|
|
3576
|
+
await this._sendDescription(connection, answer);
|
|
3577
|
+
this._onSessionNegotiated(connection);
|
|
3578
|
+
} catch (err) {
|
|
3579
|
+
this._abortConnection(connection, new Error("Error handling a remote offer.", {
|
|
3580
|
+
cause: err
|
|
3581
|
+
}));
|
|
3582
|
+
}
|
|
3583
|
+
});
|
|
3584
|
+
break;
|
|
3585
|
+
}
|
|
3586
|
+
case "answer":
|
|
3587
|
+
await this._offerProcessingMutex.executeSynchronized(async () => {
|
|
3588
|
+
try {
|
|
3589
|
+
if (isRemoteDescriptionSet(connection, data)) {
|
|
3590
|
+
return;
|
|
3591
|
+
}
|
|
3592
|
+
if (connection.signalingState !== "have-local-offer") {
|
|
3593
|
+
this._abortConnection(connection, new Error(`Unexpected answer from remote peer, signalingState was ${connection.signalingState}.`));
|
|
3594
|
+
return;
|
|
3595
|
+
}
|
|
3596
|
+
await connection.setRemoteDescription({
|
|
3597
|
+
type: data.type,
|
|
3598
|
+
sdp: data.sdp
|
|
3599
|
+
});
|
|
3600
|
+
this._onSessionNegotiated(connection);
|
|
3601
|
+
} catch (err) {
|
|
3602
|
+
this._abortConnection(connection, new Error("Error handling a remote answer.", {
|
|
3603
|
+
cause: err
|
|
3604
|
+
}));
|
|
3605
|
+
}
|
|
3606
|
+
});
|
|
3607
|
+
break;
|
|
3608
|
+
case "candidate":
|
|
3609
|
+
void this._processIceCandidate(connection, data.candidate);
|
|
3610
|
+
break;
|
|
3611
|
+
default:
|
|
3612
|
+
this._abortConnection(connection, new Error(`Unknown signal type ${data.type}.`));
|
|
3613
|
+
break;
|
|
3382
3614
|
}
|
|
3383
|
-
|
|
3615
|
+
log13("signal processed", void 0, {
|
|
3384
3616
|
F: __dxlog_file14,
|
|
3385
|
-
L:
|
|
3617
|
+
L: 330,
|
|
3386
3618
|
S: this,
|
|
3387
|
-
|
|
3388
|
-
"this.transports.has(proxyId)",
|
|
3389
|
-
""
|
|
3390
|
-
]
|
|
3619
|
+
C: (f, a) => f(...a)
|
|
3391
3620
|
});
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
await
|
|
3396
|
-
|
|
3621
|
+
}
|
|
3622
|
+
async _processIceCandidate(connection, candidate) {
|
|
3623
|
+
try {
|
|
3624
|
+
await this._readyForCandidates.wait();
|
|
3625
|
+
if (connection === this._connection) {
|
|
3626
|
+
log13("adding ice candidate", {
|
|
3627
|
+
candidate
|
|
3628
|
+
}, {
|
|
3629
|
+
F: __dxlog_file14,
|
|
3630
|
+
L: 338,
|
|
3631
|
+
S: this,
|
|
3632
|
+
C: (f, a) => f(...a)
|
|
3633
|
+
});
|
|
3634
|
+
await connection.addIceCandidate(candidate);
|
|
3635
|
+
}
|
|
3636
|
+
} catch (err) {
|
|
3637
|
+
log13.catch(err, void 0, {
|
|
3638
|
+
F: __dxlog_file14,
|
|
3639
|
+
L: 342,
|
|
3640
|
+
S: this,
|
|
3641
|
+
C: (f, a) => f(...a)
|
|
3397
3642
|
});
|
|
3398
3643
|
}
|
|
3399
3644
|
}
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3645
|
+
_onSessionNegotiated(connection) {
|
|
3646
|
+
if (connection === this._connection) {
|
|
3647
|
+
log13("ready to process ice candidates", void 0, {
|
|
3648
|
+
F: __dxlog_file14,
|
|
3649
|
+
L: 348,
|
|
3650
|
+
S: this,
|
|
3651
|
+
C: (f, a) => f(...a)
|
|
3652
|
+
});
|
|
3653
|
+
this._readyForCandidates.wake();
|
|
3654
|
+
} else {
|
|
3655
|
+
log13.warn("session was negotiated after connection became inactive", void 0, {
|
|
3656
|
+
F: __dxlog_file14,
|
|
3657
|
+
L: 351,
|
|
3658
|
+
S: this,
|
|
3659
|
+
C: (f, a) => f(...a)
|
|
3660
|
+
});
|
|
3405
3661
|
}
|
|
3406
|
-
|
|
3662
|
+
}
|
|
3663
|
+
_onConnectionCallbackAfterClose(callback, connection) {
|
|
3664
|
+
log13.warn("callback invoked after a connection was destroyed, this is probably a bug", {
|
|
3665
|
+
callback,
|
|
3666
|
+
state: connection.connectionState
|
|
3667
|
+
}, {
|
|
3407
3668
|
F: __dxlog_file14,
|
|
3408
|
-
L:
|
|
3669
|
+
L: 356,
|
|
3409
3670
|
S: this,
|
|
3410
3671
|
C: (f, a) => f(...a)
|
|
3411
3672
|
});
|
|
3673
|
+
this._safeCloseConnection(connection);
|
|
3412
3674
|
}
|
|
3675
|
+
_safeCloseConnection(connection = this._connection) {
|
|
3676
|
+
const resetFields = this._connection && connection === this._connection;
|
|
3677
|
+
try {
|
|
3678
|
+
connection?.close();
|
|
3679
|
+
} catch (err) {
|
|
3680
|
+
log13.catch(err, void 0, {
|
|
3681
|
+
F: __dxlog_file14,
|
|
3682
|
+
L: 368,
|
|
3683
|
+
S: this,
|
|
3684
|
+
C: (f, a) => f(...a)
|
|
3685
|
+
});
|
|
3686
|
+
}
|
|
3687
|
+
if (resetFields) {
|
|
3688
|
+
this._connection = void 0;
|
|
3689
|
+
this._dataChannels.clear();
|
|
3690
|
+
this._readyForCandidates.wake();
|
|
3691
|
+
void this._factory.onConnectionDestroyed().catch((err) => log13.catch(err, void 0, {
|
|
3692
|
+
F: __dxlog_file14,
|
|
3693
|
+
L: 374,
|
|
3694
|
+
S: this,
|
|
3695
|
+
C: (f, a) => f(...a)
|
|
3696
|
+
}));
|
|
3697
|
+
for (const [_, pendingCallback] of this._channelCreatedCallbacks.entries()) {
|
|
3698
|
+
pendingCallback.reject("Connection closed.");
|
|
3699
|
+
}
|
|
3700
|
+
this._channelCreatedCallbacks.clear();
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
async _loadConnectionConfig() {
|
|
3704
|
+
const config = {
|
|
3705
|
+
...this._options.webrtcConfig
|
|
3706
|
+
};
|
|
3707
|
+
try {
|
|
3708
|
+
const providedIceServers = await this._options.iceProvider?.getIceServers() ?? [];
|
|
3709
|
+
if (providedIceServers.length > 0) {
|
|
3710
|
+
config.iceServers = [
|
|
3711
|
+
...config.iceServers ?? [],
|
|
3712
|
+
...providedIceServers
|
|
3713
|
+
];
|
|
3714
|
+
}
|
|
3715
|
+
} catch (error) {
|
|
3716
|
+
log13.catch(error, void 0, {
|
|
3717
|
+
F: __dxlog_file14,
|
|
3718
|
+
L: 390,
|
|
3719
|
+
S: this,
|
|
3720
|
+
C: (f, a) => f(...a)
|
|
3721
|
+
});
|
|
3722
|
+
}
|
|
3723
|
+
return config;
|
|
3724
|
+
}
|
|
3725
|
+
async _sendIceCandidate(candidate) {
|
|
3726
|
+
try {
|
|
3727
|
+
await this._options.sendSignal({
|
|
3728
|
+
payload: {
|
|
3729
|
+
data: {
|
|
3730
|
+
type: "candidate",
|
|
3731
|
+
candidate: {
|
|
3732
|
+
candidate: candidate.candidate,
|
|
3733
|
+
// These fields never seem to be not null, but connecting to Chrome doesn't work if they are.
|
|
3734
|
+
sdpMLineIndex: candidate.sdpMLineIndex ?? "0",
|
|
3735
|
+
sdpMid: candidate.sdpMid ?? "0"
|
|
3736
|
+
}
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
});
|
|
3740
|
+
} catch (err) {
|
|
3741
|
+
log13.warn("signaling error", {
|
|
3742
|
+
err
|
|
3743
|
+
}, {
|
|
3744
|
+
F: __dxlog_file14,
|
|
3745
|
+
L: 411,
|
|
3746
|
+
S: this,
|
|
3747
|
+
C: (f, a) => f(...a)
|
|
3748
|
+
});
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3751
|
+
async _sendDescription(connection, description) {
|
|
3752
|
+
if (connection !== this._connection) {
|
|
3753
|
+
return;
|
|
3754
|
+
}
|
|
3755
|
+
const data = {
|
|
3756
|
+
type: description.type,
|
|
3757
|
+
sdp: description.sdp
|
|
3758
|
+
};
|
|
3759
|
+
await this._options.sendSignal({
|
|
3760
|
+
payload: {
|
|
3761
|
+
data
|
|
3762
|
+
}
|
|
3763
|
+
});
|
|
3764
|
+
}
|
|
3765
|
+
get _connectionInfo() {
|
|
3766
|
+
const connectionInfo = this._connection && {
|
|
3767
|
+
connectionState: this._connection.connectionState,
|
|
3768
|
+
iceConnectionState: this._connection.iceConnectionState,
|
|
3769
|
+
iceGatheringState: this._connection.iceGatheringState,
|
|
3770
|
+
signalingState: this._connection.signalingState,
|
|
3771
|
+
remoteDescription: this._connection.remoteDescription,
|
|
3772
|
+
localDescription: this._connection.localDescription
|
|
3773
|
+
};
|
|
3774
|
+
return {
|
|
3775
|
+
...connectionInfo,
|
|
3776
|
+
ts: Date.now(),
|
|
3777
|
+
remotePeerKey: this._options.remotePeerKey,
|
|
3778
|
+
channels: [
|
|
3779
|
+
...this._transportChannels.keys()
|
|
3780
|
+
].map((topic) => topic),
|
|
3781
|
+
config: this._connection?.getConfiguration()
|
|
3782
|
+
};
|
|
3783
|
+
}
|
|
3784
|
+
get _loggerContext() {
|
|
3785
|
+
return {
|
|
3786
|
+
ownPeerKey: this._options.ownPeerKey,
|
|
3787
|
+
remotePeerKey: this._options.remotePeerKey,
|
|
3788
|
+
initiator: this._initiator,
|
|
3789
|
+
channels: this._transportChannels.size
|
|
3790
|
+
};
|
|
3791
|
+
}
|
|
3792
|
+
};
|
|
3793
|
+
_ts_decorate6([
|
|
3794
|
+
synchronized5
|
|
3795
|
+
], RtcPeerConnection.prototype, "_openConnection", null);
|
|
3796
|
+
_ts_decorate6([
|
|
3797
|
+
synchronized5
|
|
3798
|
+
], RtcPeerConnection.prototype, "_lockAndAbort", null);
|
|
3799
|
+
_ts_decorate6([
|
|
3800
|
+
synchronized5
|
|
3801
|
+
], RtcPeerConnection.prototype, "_lockAndCloseConnection", null);
|
|
3802
|
+
_ts_decorate6([
|
|
3803
|
+
synchronized5
|
|
3804
|
+
], RtcPeerConnection.prototype, "onSignal", null);
|
|
3805
|
+
_ts_decorate6([
|
|
3806
|
+
trace4.info()
|
|
3807
|
+
], RtcPeerConnection.prototype, "_connectionInfo", null);
|
|
3808
|
+
_ts_decorate6([
|
|
3809
|
+
logInfo4
|
|
3810
|
+
], RtcPeerConnection.prototype, "_loggerContext", null);
|
|
3811
|
+
RtcPeerConnection = _ts_decorate6([
|
|
3812
|
+
trace4.resource()
|
|
3813
|
+
], RtcPeerConnection);
|
|
3814
|
+
var isRemoteDescriptionSet = (connection, data) => {
|
|
3815
|
+
if (!connection.remoteDescription?.type || connection.remoteDescription?.type !== data.type) {
|
|
3816
|
+
return false;
|
|
3817
|
+
}
|
|
3818
|
+
return areSdpEqual(connection.remoteDescription.sdp, data.sdp);
|
|
3819
|
+
};
|
|
3820
|
+
var createIceFailureError = (details) => {
|
|
3821
|
+
const candidateErrors = details.map(({ url, errorCode, errorText }) => `${errorCode} ${url}: ${errorText}`);
|
|
3822
|
+
return new ConnectivityError3(`ICE failed:
|
|
3823
|
+
${candidateErrors.join("\n")}`);
|
|
3413
3824
|
};
|
|
3414
3825
|
|
|
3415
|
-
// packages/core/mesh/network-manager/src/transport/
|
|
3826
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-factory.ts
|
|
3827
|
+
var createRtcTransportFactory = (webrtcConfig, iceProvider) => {
|
|
3828
|
+
const connectionFactory = getRtcConnectionFactory();
|
|
3829
|
+
return {
|
|
3830
|
+
createTransport: (options) => {
|
|
3831
|
+
const connection = new RtcPeerConnection(connectionFactory, {
|
|
3832
|
+
ownPeerKey: options.ownPeerKey,
|
|
3833
|
+
remotePeerKey: options.remotePeerKey,
|
|
3834
|
+
sendSignal: options.sendSignal,
|
|
3835
|
+
webrtcConfig,
|
|
3836
|
+
iceProvider
|
|
3837
|
+
});
|
|
3838
|
+
return connection.createTransportChannel(options);
|
|
3839
|
+
}
|
|
3840
|
+
};
|
|
3841
|
+
};
|
|
3842
|
+
|
|
3843
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-proxy.ts
|
|
3416
3844
|
import { Writable } from "@dxos/node-std/stream";
|
|
3417
|
-
import { Event as
|
|
3418
|
-
import {
|
|
3845
|
+
import { Event as Event8, scheduleTask as scheduleTask4 } from "@dxos/async";
|
|
3846
|
+
import { Resource as Resource2 } from "@dxos/context";
|
|
3419
3847
|
import { ErrorStream as ErrorStream5 } from "@dxos/debug";
|
|
3420
3848
|
import { invariant as invariant13 } from "@dxos/invariant";
|
|
3421
|
-
import { PublicKey as
|
|
3849
|
+
import { PublicKey as PublicKey10 } from "@dxos/keys";
|
|
3422
3850
|
import { log as log14 } from "@dxos/log";
|
|
3423
|
-
import { ConnectionResetError as
|
|
3424
|
-
import { ConnectionState as
|
|
3851
|
+
import { ConnectionResetError as ConnectionResetError2, ConnectivityError as ConnectivityError4, TimeoutError as TimeoutError3 } from "@dxos/protocols";
|
|
3852
|
+
import { ConnectionState as ConnectionState3 } from "@dxos/protocols/proto/dxos/mesh/bridge";
|
|
3425
3853
|
import { arrayToBuffer } from "@dxos/util";
|
|
3426
|
-
var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/
|
|
3854
|
+
var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-proxy.ts";
|
|
3427
3855
|
var RPC_TIMEOUT = 1e4;
|
|
3856
|
+
var CLOSE_RPC_TIMEOUT = 3e3;
|
|
3428
3857
|
var RESP_MIN_THRESHOLD = 500;
|
|
3429
|
-
var
|
|
3430
|
-
var SimplePeerTransportProxy = class {
|
|
3858
|
+
var RtcTransportProxy = class extends Resource2 {
|
|
3431
3859
|
constructor(_options) {
|
|
3860
|
+
super();
|
|
3432
3861
|
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();
|
|
3862
|
+
this._proxyId = PublicKey10.random();
|
|
3863
|
+
this.closed = new Event8();
|
|
3864
|
+
this.connected = new Event8();
|
|
3441
3865
|
this.errors = new ErrorStream5();
|
|
3442
|
-
this._closed = false;
|
|
3443
|
-
}
|
|
3444
|
-
get isOpen() {
|
|
3445
|
-
return !this._closed;
|
|
3446
3866
|
}
|
|
3447
|
-
async
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3867
|
+
async _open() {
|
|
3868
|
+
let stream;
|
|
3869
|
+
try {
|
|
3870
|
+
stream = this._options.bridgeService.open({
|
|
3871
|
+
proxyId: this._proxyId,
|
|
3872
|
+
remotePeerKey: this._options.remotePeerKey,
|
|
3873
|
+
ownPeerKey: this._options.ownPeerKey,
|
|
3874
|
+
topic: this._options.topic,
|
|
3875
|
+
initiator: this._options.initiator ?? false
|
|
3876
|
+
}, {
|
|
3877
|
+
timeout: RPC_TIMEOUT
|
|
3878
|
+
});
|
|
3879
|
+
} catch (error) {
|
|
3880
|
+
this.errors.raise(error);
|
|
3881
|
+
return;
|
|
3882
|
+
}
|
|
3883
|
+
this._serviceStream = stream;
|
|
3884
|
+
stream.waitUntilReady().then(() => {
|
|
3885
|
+
stream.subscribe(async (event) => {
|
|
3886
|
+
log14("rtc transport proxy event", event, {
|
|
3457
3887
|
F: __dxlog_file15,
|
|
3458
3888
|
L: 66,
|
|
3459
3889
|
S: this,
|
|
@@ -3466,20 +3896,34 @@ var SimplePeerTransportProxy = class {
|
|
|
3466
3896
|
} else if (event.signal) {
|
|
3467
3897
|
await this._handleSignal(event.signal);
|
|
3468
3898
|
}
|
|
3899
|
+
}, (err) => {
|
|
3900
|
+
log14("rtc bridge stream closed", {
|
|
3901
|
+
err
|
|
3902
|
+
}, {
|
|
3903
|
+
F: __dxlog_file15,
|
|
3904
|
+
L: 76,
|
|
3905
|
+
S: this,
|
|
3906
|
+
C: (f, a) => f(...a)
|
|
3907
|
+
});
|
|
3908
|
+
if (err) {
|
|
3909
|
+
this._raiseIfOpen(err);
|
|
3910
|
+
} else {
|
|
3911
|
+
void this.close();
|
|
3912
|
+
}
|
|
3469
3913
|
});
|
|
3470
|
-
const
|
|
3914
|
+
const connectorStream = new Writable({
|
|
3471
3915
|
write: (chunk, _, callback) => {
|
|
3472
|
-
const
|
|
3916
|
+
const sendStartMs = Date.now();
|
|
3473
3917
|
this._options.bridgeService.sendData({
|
|
3474
3918
|
proxyId: this._proxyId,
|
|
3475
3919
|
payload: chunk
|
|
3476
3920
|
}, {
|
|
3477
3921
|
timeout: RPC_TIMEOUT
|
|
3478
3922
|
}).then(() => {
|
|
3479
|
-
if (
|
|
3923
|
+
if (Date.now() - sendStartMs > RESP_MIN_THRESHOLD) {
|
|
3480
3924
|
log14("slow response, delaying callback", void 0, {
|
|
3481
3925
|
F: __dxlog_file15,
|
|
3482
|
-
L:
|
|
3926
|
+
L: 93,
|
|
3483
3927
|
S: this,
|
|
3484
3928
|
C: (f, a) => f(...a)
|
|
3485
3929
|
});
|
|
@@ -3487,60 +3931,41 @@ var SimplePeerTransportProxy = class {
|
|
|
3487
3931
|
} else {
|
|
3488
3932
|
callback();
|
|
3489
3933
|
}
|
|
3490
|
-
this._timeoutCount = 0;
|
|
3491
3934
|
}, (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
|
-
}
|
|
3935
|
+
callback();
|
|
3936
|
+
this._raiseIfOpen(err);
|
|
3512
3937
|
});
|
|
3513
3938
|
}
|
|
3514
3939
|
});
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
err
|
|
3518
|
-
}, {
|
|
3519
|
-
F: __dxlog_file15,
|
|
3520
|
-
L: 114,
|
|
3521
|
-
S: this,
|
|
3522
|
-
C: (f, a) => f(...a)
|
|
3523
|
-
});
|
|
3940
|
+
connectorStream.on("error", (err) => {
|
|
3941
|
+
this._raiseIfOpen(err);
|
|
3524
3942
|
});
|
|
3525
|
-
this._options.stream.pipe(
|
|
3526
|
-
}, (error) =>
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3943
|
+
this._options.stream.pipe(connectorStream);
|
|
3944
|
+
}, (error) => {
|
|
3945
|
+
if (error) {
|
|
3946
|
+
this._raiseIfOpen(error);
|
|
3947
|
+
} else {
|
|
3948
|
+
void this.close();
|
|
3949
|
+
}
|
|
3950
|
+
});
|
|
3532
3951
|
}
|
|
3533
|
-
async
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3952
|
+
async _close() {
|
|
3953
|
+
try {
|
|
3954
|
+
await this._serviceStream?.close();
|
|
3955
|
+
this._serviceStream = void 0;
|
|
3956
|
+
} catch (err) {
|
|
3957
|
+
log14.catch(err, void 0, {
|
|
3958
|
+
F: __dxlog_file15,
|
|
3959
|
+
L: 128,
|
|
3960
|
+
S: this,
|
|
3961
|
+
C: (f, a) => f(...a)
|
|
3962
|
+
});
|
|
3537
3963
|
}
|
|
3538
|
-
await this._serviceStream.close();
|
|
3539
3964
|
try {
|
|
3540
3965
|
await this._options.bridgeService.close({
|
|
3541
3966
|
proxyId: this._proxyId
|
|
3542
3967
|
}, {
|
|
3543
|
-
timeout:
|
|
3968
|
+
timeout: CLOSE_RPC_TIMEOUT
|
|
3544
3969
|
});
|
|
3545
3970
|
} catch (err) {
|
|
3546
3971
|
log14.catch(err, void 0, {
|
|
@@ -3551,7 +3976,6 @@ var SimplePeerTransportProxy = class {
|
|
|
3551
3976
|
});
|
|
3552
3977
|
}
|
|
3553
3978
|
this.closed.emit();
|
|
3554
|
-
this._closed = true;
|
|
3555
3979
|
}
|
|
3556
3980
|
async onSignal(signal) {
|
|
3557
3981
|
this._options.bridgeService.sendSignal({
|
|
@@ -3559,581 +3983,347 @@ var SimplePeerTransportProxy = class {
|
|
|
3559
3983
|
signal
|
|
3560
3984
|
}, {
|
|
3561
3985
|
timeout: RPC_TIMEOUT
|
|
3562
|
-
}).catch((err) => this.
|
|
3986
|
+
}).catch((err) => this._raiseIfOpen(decodeError(err)));
|
|
3563
3987
|
}
|
|
3564
3988
|
async _handleConnection(connectionEvent) {
|
|
3565
3989
|
if (connectionEvent.error) {
|
|
3566
3990
|
this.errors.raise(decodeError(connectionEvent.error));
|
|
3991
|
+
return;
|
|
3567
3992
|
}
|
|
3568
3993
|
switch (connectionEvent.state) {
|
|
3569
|
-
case
|
|
3994
|
+
case ConnectionState3.CONNECTED: {
|
|
3570
3995
|
this.connected.emit();
|
|
3571
3996
|
break;
|
|
3572
3997
|
}
|
|
3573
|
-
case
|
|
3998
|
+
case ConnectionState3.CLOSED: {
|
|
3574
3999
|
await this.close();
|
|
3575
4000
|
break;
|
|
3576
4001
|
}
|
|
3577
4002
|
}
|
|
3578
4003
|
}
|
|
3579
4004
|
_handleData(dataEvent) {
|
|
3580
|
-
|
|
4005
|
+
try {
|
|
4006
|
+
this._options.stream.write(arrayToBuffer(dataEvent.payload));
|
|
4007
|
+
} catch (error) {
|
|
4008
|
+
this._raiseIfOpen(error);
|
|
4009
|
+
}
|
|
3581
4010
|
}
|
|
3582
4011
|
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();
|
|
4012
|
+
try {
|
|
4013
|
+
await this._options.sendSignal(signalEvent.payload);
|
|
4014
|
+
} catch (error) {
|
|
4015
|
+
const type = signalEvent.payload.payload.data?.type;
|
|
4016
|
+
if (type === "offer" || type === "answer") {
|
|
4017
|
+
this._raiseIfOpen(new ConnectivityError4(`Session establishment failed: ${type} couldn't be sent.`));
|
|
4018
|
+
}
|
|
3621
4019
|
}
|
|
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
|
-
}
|
|
3699
|
-
get isOpen() {
|
|
3700
|
-
return !!this._peer && !this._closed;
|
|
3701
4020
|
}
|
|
3702
|
-
async
|
|
3703
|
-
|
|
3704
|
-
this.
|
|
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
|
|
4021
|
+
async getDetails() {
|
|
4022
|
+
try {
|
|
4023
|
+
const response = await this._options.bridgeService.getDetails({
|
|
4024
|
+
proxyId: this._proxyId
|
|
3731
4025
|
}, {
|
|
3732
|
-
|
|
3733
|
-
L: 97,
|
|
3734
|
-
S: this,
|
|
3735
|
-
C: (f, a) => f(...a)
|
|
4026
|
+
timeout: RPC_TIMEOUT
|
|
3736
4027
|
});
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
4028
|
+
return response.details;
|
|
4029
|
+
} catch (err) {
|
|
4030
|
+
return "bridge-svc unreachable";
|
|
4031
|
+
}
|
|
4032
|
+
}
|
|
4033
|
+
async getStats() {
|
|
4034
|
+
try {
|
|
4035
|
+
const response = await this._options.bridgeService.getStats({
|
|
4036
|
+
proxyId: this._proxyId
|
|
3741
4037
|
}, {
|
|
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)
|
|
4038
|
+
timeout: RPC_TIMEOUT
|
|
3826
4039
|
});
|
|
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);
|
|
4040
|
+
return response.stats;
|
|
4041
|
+
} catch (err) {
|
|
4042
|
+
return {
|
|
4043
|
+
bytesSent: 0,
|
|
4044
|
+
bytesReceived: 0,
|
|
4045
|
+
packetsSent: 0,
|
|
4046
|
+
packetsReceived: 0,
|
|
4047
|
+
rawStats: "bridge-svc unreachable"
|
|
3844
4048
|
};
|
|
3845
4049
|
}
|
|
3846
|
-
_LibDataChannelTransport._instanceCount++;
|
|
3847
4050
|
}
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
4051
|
+
_raiseIfOpen(error) {
|
|
4052
|
+
if (this.isOpen) {
|
|
4053
|
+
this.errors.raise(error);
|
|
4054
|
+
} else {
|
|
4055
|
+
log14.info("error swallowed because transport was closed", {
|
|
4056
|
+
message: error.message
|
|
4057
|
+
}, {
|
|
4058
|
+
F: __dxlog_file15,
|
|
4059
|
+
L: 215,
|
|
4060
|
+
S: this,
|
|
4061
|
+
C: (f, a) => f(...a)
|
|
4062
|
+
});
|
|
3852
4063
|
}
|
|
3853
4064
|
}
|
|
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;
|
|
4065
|
+
/**
|
|
4066
|
+
* Called when underlying proxy service becomes unavailable.
|
|
4067
|
+
*/
|
|
4068
|
+
forceClose() {
|
|
4069
|
+
void this._serviceStream?.close();
|
|
3866
4070
|
this.closed.emit();
|
|
3867
4071
|
}
|
|
4072
|
+
};
|
|
4073
|
+
var RtcTransportProxyFactory = class {
|
|
4074
|
+
constructor() {
|
|
4075
|
+
this._connections = /* @__PURE__ */ new Set();
|
|
4076
|
+
}
|
|
3868
4077
|
/**
|
|
3869
|
-
*
|
|
4078
|
+
* Sets the current BridgeService to be used to open connections.
|
|
4079
|
+
* Calling this method will close any existing connections.
|
|
3870
4080
|
*/
|
|
3871
|
-
|
|
3872
|
-
this.
|
|
3873
|
-
this.
|
|
3874
|
-
|
|
4081
|
+
setBridgeService(bridgeService) {
|
|
4082
|
+
this._bridgeService = bridgeService;
|
|
4083
|
+
for (const connection of this._connections) {
|
|
4084
|
+
connection.forceClose();
|
|
4085
|
+
}
|
|
4086
|
+
return this;
|
|
4087
|
+
}
|
|
4088
|
+
createTransport(options) {
|
|
4089
|
+
invariant13(this._bridgeService, "RtcTransportProxyFactory is not ready to open connections", {
|
|
4090
|
+
F: __dxlog_file15,
|
|
4091
|
+
L: 245,
|
|
4092
|
+
S: this,
|
|
4093
|
+
A: [
|
|
4094
|
+
"this._bridgeService",
|
|
4095
|
+
"'RtcTransportProxyFactory is not ready to open connections'"
|
|
4096
|
+
]
|
|
4097
|
+
});
|
|
4098
|
+
const transport = new RtcTransportProxy({
|
|
4099
|
+
...options,
|
|
4100
|
+
bridgeService: this._bridgeService
|
|
4101
|
+
});
|
|
4102
|
+
this._connections.add(transport);
|
|
4103
|
+
transport.closed.on(() => this._connections.delete(transport));
|
|
4104
|
+
return transport;
|
|
4105
|
+
}
|
|
4106
|
+
};
|
|
4107
|
+
var decodeError = (err) => {
|
|
4108
|
+
const message = typeof err === "string" ? err : err.message;
|
|
4109
|
+
if (message.includes("CONNECTION_RESET")) {
|
|
4110
|
+
return new ConnectionResetError2(message);
|
|
4111
|
+
} else if (message.includes("TIMEOUT")) {
|
|
4112
|
+
return new TimeoutError3(message);
|
|
4113
|
+
} else if (message.includes("CONNECTIVITY_ERROR")) {
|
|
4114
|
+
return new ConnectivityError4(message);
|
|
4115
|
+
} else {
|
|
4116
|
+
return typeof err === "string" ? new Error(err) : err;
|
|
4117
|
+
}
|
|
4118
|
+
};
|
|
4119
|
+
|
|
4120
|
+
// packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-service.ts
|
|
4121
|
+
import { Duplex as Duplex2 } from "@dxos/node-std/stream";
|
|
4122
|
+
import { Stream } from "@dxos/codec-protobuf";
|
|
4123
|
+
import { invariant as invariant14 } from "@dxos/invariant";
|
|
4124
|
+
import { PublicKey as PublicKey11 } from "@dxos/keys";
|
|
4125
|
+
import { log as log15 } from "@dxos/log";
|
|
4126
|
+
import { ConnectionState as ConnectionState4 } from "@dxos/protocols/proto/dxos/mesh/bridge";
|
|
4127
|
+
import { ComplexMap as ComplexMap8 } from "@dxos/util";
|
|
4128
|
+
var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-service.ts";
|
|
4129
|
+
var RtcTransportService = class {
|
|
4130
|
+
constructor(webrtcConfig, iceProvider, _transportFactory = createRtcTransportFactory(webrtcConfig, iceProvider)) {
|
|
4131
|
+
this._transportFactory = _transportFactory;
|
|
4132
|
+
this._openTransports = new ComplexMap8(PublicKey11.hash);
|
|
4133
|
+
}
|
|
4134
|
+
hasOpenTransports() {
|
|
4135
|
+
return this._openTransports.size > 0;
|
|
4136
|
+
}
|
|
4137
|
+
open(request) {
|
|
4138
|
+
const existingTransport = this._openTransports.get(request.proxyId);
|
|
4139
|
+
if (existingTransport) {
|
|
4140
|
+
log15.error("requesting a new transport bridge for an existing proxy", void 0, {
|
|
3875
4141
|
F: __dxlog_file16,
|
|
3876
|
-
L:
|
|
4142
|
+
L: 53,
|
|
3877
4143
|
S: this,
|
|
3878
4144
|
C: (f, a) => f(...a)
|
|
3879
4145
|
});
|
|
3880
|
-
|
|
4146
|
+
void this._safeCloseTransport(existingTransport);
|
|
4147
|
+
this._openTransports.delete(request.proxyId);
|
|
4148
|
+
}
|
|
4149
|
+
return new Stream(({ ready, next, close }) => {
|
|
4150
|
+
const pushNewState = createStateUpdater(next);
|
|
4151
|
+
const transportStream = new Duplex2({
|
|
3881
4152
|
read: () => {
|
|
4153
|
+
const callbacks = [
|
|
4154
|
+
...transportState.writeProcessedCallbacks
|
|
4155
|
+
];
|
|
4156
|
+
transportState.writeProcessedCallbacks.length = 0;
|
|
4157
|
+
callbacks.forEach((cb) => cb());
|
|
3882
4158
|
},
|
|
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
|
-
});
|
|
4159
|
+
write: function(chunk, _, callback) {
|
|
4160
|
+
next({
|
|
4161
|
+
data: {
|
|
4162
|
+
payload: chunk
|
|
3901
4163
|
}
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
callback();
|
|
3905
|
-
}
|
|
4164
|
+
});
|
|
4165
|
+
callback();
|
|
3906
4166
|
}
|
|
3907
4167
|
});
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
4168
|
+
const transport = this._transportFactory.createTransport({
|
|
4169
|
+
initiator: request.initiator,
|
|
4170
|
+
topic: request.topic,
|
|
4171
|
+
ownPeerKey: request.ownPeerKey,
|
|
4172
|
+
remotePeerKey: request.remotePeerKey,
|
|
4173
|
+
stream: transportStream,
|
|
4174
|
+
sendSignal: async (signal) => {
|
|
4175
|
+
next({
|
|
4176
|
+
signal: {
|
|
4177
|
+
payload: signal
|
|
4178
|
+
}
|
|
4179
|
+
});
|
|
4180
|
+
}
|
|
3921
4181
|
});
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
4182
|
+
const transportState = {
|
|
4183
|
+
proxyId: request.proxyId,
|
|
4184
|
+
transport,
|
|
4185
|
+
connectorStream: transportStream,
|
|
4186
|
+
writeProcessedCallbacks: []
|
|
4187
|
+
};
|
|
4188
|
+
pushNewState(ConnectionState4.CONNECTING);
|
|
4189
|
+
transport.connected.on(() => pushNewState(ConnectionState4.CONNECTED));
|
|
4190
|
+
transport.errors.handle(async (err) => {
|
|
4191
|
+
pushNewState(ConnectionState4.CLOSED, err);
|
|
4192
|
+
void this._safeCloseTransport(transportState);
|
|
4193
|
+
close(err);
|
|
4194
|
+
});
|
|
4195
|
+
transport.closed.on(async () => {
|
|
4196
|
+
pushNewState(ConnectionState4.CLOSED);
|
|
4197
|
+
void this._safeCloseTransport(transportState);
|
|
4198
|
+
close();
|
|
4199
|
+
});
|
|
4200
|
+
this._openTransports.set(request.proxyId, transportState);
|
|
4201
|
+
transport.open().catch(async (err) => {
|
|
4202
|
+
pushNewState(ConnectionState4.CLOSED, err);
|
|
4203
|
+
void this._safeCloseTransport(transportState);
|
|
4204
|
+
close(err);
|
|
4205
|
+
});
|
|
4206
|
+
ready();
|
|
4207
|
+
});
|
|
3940
4208
|
}
|
|
3941
|
-
async
|
|
3942
|
-
|
|
4209
|
+
async sendSignal({ proxyId, signal }) {
|
|
4210
|
+
const transport = this._openTransports.get(proxyId);
|
|
4211
|
+
invariant14(transport, void 0, {
|
|
3943
4212
|
F: __dxlog_file16,
|
|
3944
|
-
L:
|
|
4213
|
+
L: 121,
|
|
3945
4214
|
S: this,
|
|
3946
4215
|
A: [
|
|
3947
|
-
"
|
|
3948
|
-
"
|
|
4216
|
+
"transport",
|
|
4217
|
+
""
|
|
3949
4218
|
]
|
|
3950
4219
|
});
|
|
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}`;
|
|
4220
|
+
await transport.transport.onSignal(signal);
|
|
4052
4221
|
}
|
|
4053
|
-
async
|
|
4054
|
-
const
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
}
|
|
4222
|
+
async getDetails({ proxyId }) {
|
|
4223
|
+
const transport = this._openTransports.get(proxyId);
|
|
4224
|
+
invariant14(transport, void 0, {
|
|
4225
|
+
F: __dxlog_file16,
|
|
4226
|
+
L: 128,
|
|
4227
|
+
S: this,
|
|
4228
|
+
A: [
|
|
4229
|
+
"transport",
|
|
4230
|
+
""
|
|
4231
|
+
]
|
|
4232
|
+
});
|
|
4064
4233
|
return {
|
|
4065
|
-
|
|
4066
|
-
bytesReceived: stats.transport.bytesReceived,
|
|
4067
|
-
packetsSent: 0,
|
|
4068
|
-
packetsReceived: 0,
|
|
4069
|
-
rawStats: stats.raw
|
|
4234
|
+
details: await transport.transport.getDetails()
|
|
4070
4235
|
};
|
|
4071
4236
|
}
|
|
4072
|
-
async
|
|
4073
|
-
|
|
4237
|
+
async getStats({ proxyId }) {
|
|
4238
|
+
const transport = this._openTransports.get(proxyId);
|
|
4239
|
+
invariant14(transport, void 0, {
|
|
4074
4240
|
F: __dxlog_file16,
|
|
4075
|
-
L:
|
|
4241
|
+
L: 135,
|
|
4076
4242
|
S: this,
|
|
4077
4243
|
A: [
|
|
4078
|
-
"
|
|
4079
|
-
"
|
|
4244
|
+
"transport",
|
|
4245
|
+
""
|
|
4080
4246
|
]
|
|
4081
4247
|
});
|
|
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
4248
|
return {
|
|
4093
|
-
transport
|
|
4094
|
-
selectedCandidatePair,
|
|
4095
|
-
remoteCandidate,
|
|
4096
|
-
raw: Object.fromEntries(stats)
|
|
4249
|
+
stats: await transport.transport.getStats()
|
|
4097
4250
|
};
|
|
4098
4251
|
}
|
|
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.");
|
|
4252
|
+
async sendData({ proxyId, payload }) {
|
|
4253
|
+
const transport = this._openTransports.get(proxyId);
|
|
4254
|
+
invariant14(transport, void 0, {
|
|
4255
|
+
F: __dxlog_file16,
|
|
4256
|
+
L: 142,
|
|
4257
|
+
S: this,
|
|
4258
|
+
A: [
|
|
4259
|
+
"transport",
|
|
4260
|
+
""
|
|
4261
|
+
]
|
|
4262
|
+
});
|
|
4263
|
+
const bufferHasSpace = transport.connectorStream.push(payload);
|
|
4264
|
+
if (!bufferHasSpace) {
|
|
4265
|
+
await new Promise((resolve) => {
|
|
4266
|
+
transport.writeProcessedCallbacks.push(resolve);
|
|
4267
|
+
});
|
|
4268
|
+
}
|
|
4129
4269
|
}
|
|
4130
|
-
async
|
|
4131
|
-
|
|
4270
|
+
async close({ proxyId }) {
|
|
4271
|
+
const transport = this._openTransports.get(proxyId);
|
|
4272
|
+
if (!transport) {
|
|
4273
|
+
return;
|
|
4274
|
+
}
|
|
4275
|
+
this._openTransports.delete(proxyId);
|
|
4276
|
+
await this._safeCloseTransport(transport);
|
|
4132
4277
|
}
|
|
4133
|
-
async
|
|
4134
|
-
|
|
4278
|
+
async _safeCloseTransport(transport) {
|
|
4279
|
+
if (this._openTransports.get(transport.proxyId) === transport) {
|
|
4280
|
+
this._openTransports.delete(transport.proxyId);
|
|
4281
|
+
}
|
|
4282
|
+
transport.writeProcessedCallbacks.forEach((cb) => cb());
|
|
4283
|
+
try {
|
|
4284
|
+
await transport.transport.close();
|
|
4285
|
+
} catch (error) {
|
|
4286
|
+
log15.warn("transport close error", {
|
|
4287
|
+
message: error?.message
|
|
4288
|
+
}, {
|
|
4289
|
+
F: __dxlog_file16,
|
|
4290
|
+
L: 172,
|
|
4291
|
+
S: this,
|
|
4292
|
+
C: (f, a) => f(...a)
|
|
4293
|
+
});
|
|
4294
|
+
}
|
|
4295
|
+
try {
|
|
4296
|
+
transport.connectorStream.end();
|
|
4297
|
+
} catch (error) {
|
|
4298
|
+
log15.warn("connectorStream close error", {
|
|
4299
|
+
message: error?.message
|
|
4300
|
+
}, {
|
|
4301
|
+
F: __dxlog_file16,
|
|
4302
|
+
L: 177,
|
|
4303
|
+
S: this,
|
|
4304
|
+
C: (f, a) => f(...a)
|
|
4305
|
+
});
|
|
4306
|
+
}
|
|
4307
|
+
log15("closed", void 0, {
|
|
4308
|
+
F: __dxlog_file16,
|
|
4309
|
+
L: 179,
|
|
4310
|
+
S: this,
|
|
4311
|
+
C: (f, a) => f(...a)
|
|
4312
|
+
});
|
|
4135
4313
|
}
|
|
4136
4314
|
};
|
|
4315
|
+
var createStateUpdater = (next) => {
|
|
4316
|
+
return (state, err) => {
|
|
4317
|
+
next({
|
|
4318
|
+
connection: {
|
|
4319
|
+
state,
|
|
4320
|
+
...err ? {
|
|
4321
|
+
error: err.message
|
|
4322
|
+
} : void 0
|
|
4323
|
+
}
|
|
4324
|
+
});
|
|
4325
|
+
};
|
|
4326
|
+
};
|
|
4137
4327
|
|
|
4138
4328
|
// packages/core/mesh/network-manager/src/wire-protocol.ts
|
|
4139
4329
|
import { Teleport } from "@dxos/teleport";
|
|
@@ -4160,7 +4350,6 @@ var createTeleportProtocolFactory = (onConnection, defaultParams) => {
|
|
|
4160
4350
|
};
|
|
4161
4351
|
|
|
4162
4352
|
export {
|
|
4163
|
-
process,
|
|
4164
4353
|
ConnectionState,
|
|
4165
4354
|
Connection,
|
|
4166
4355
|
createIceProvider,
|
|
@@ -4178,15 +4367,10 @@ export {
|
|
|
4178
4367
|
MemoryTransportFactory,
|
|
4179
4368
|
MemoryTransport,
|
|
4180
4369
|
TransportKind,
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
SimplePeerTransportProxyFactory,
|
|
4186
|
-
createLibDataChannelTransportFactory,
|
|
4187
|
-
LibDataChannelTransport,
|
|
4188
|
-
TcpTransportFactory,
|
|
4189
|
-
TcpTransport,
|
|
4370
|
+
createRtcTransportFactory,
|
|
4371
|
+
RtcTransportProxy,
|
|
4372
|
+
RtcTransportProxyFactory,
|
|
4373
|
+
RtcTransportService,
|
|
4190
4374
|
createTeleportProtocolFactory
|
|
4191
4375
|
};
|
|
4192
|
-
//# sourceMappingURL=chunk-
|
|
4376
|
+
//# sourceMappingURL=chunk-MKIVP7G3.mjs.map
|