@dxos/network-manager 0.8.3 → 0.8.4-main.84f28bd
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-LFKR6BAF.mjs → chunk-HQNQOWFA.mjs} +43 -43
- package/dist/lib/browser/index.mjs +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +6 -6
- package/dist/lib/browser/transport/tcp/index.mjs +1 -1
- package/dist/lib/node-esm/{chunk-QQY4BF6O.mjs → chunk-JPPMRZTH.mjs} +43 -43
- package/dist/lib/node-esm/index.mjs +1 -1
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +6 -6
- package/dist/lib/node-esm/transport/tcp/index.mjs +2 -2
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +20 -20
- package/dist/lib/node/chunk-2G6RZMS5.cjs +0 -4460
- package/dist/lib/node/chunk-2G6RZMS5.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -71
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/testing/index.cjs +0 -296
- package/dist/lib/node/testing/index.cjs.map +0 -7
- package/dist/lib/node/transport/tcp/index.cjs +0 -191
- package/dist/lib/node/transport/tcp/index.cjs.map +0 -7
- /package/dist/lib/browser/{chunk-LFKR6BAF.mjs.map → chunk-HQNQOWFA.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-QQY4BF6O.mjs.map → chunk-JPPMRZTH.mjs.map} +0 -0
|
@@ -1,4460 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
var chunk_2G6RZMS5_exports = {};
|
|
30
|
-
__export(chunk_2G6RZMS5_exports, {
|
|
31
|
-
Connection: () => Connection,
|
|
32
|
-
ConnectionLimiter: () => ConnectionLimiter,
|
|
33
|
-
ConnectionLog: () => ConnectionLog,
|
|
34
|
-
ConnectionState: () => ConnectionState,
|
|
35
|
-
EventType: () => EventType,
|
|
36
|
-
FullyConnectedTopology: () => FullyConnectedTopology,
|
|
37
|
-
MAX_CONCURRENT_INITIATING_CONNECTIONS: () => MAX_CONCURRENT_INITIATING_CONNECTIONS,
|
|
38
|
-
MMSTTopology: () => MMSTTopology,
|
|
39
|
-
MemoryTransport: () => MemoryTransport,
|
|
40
|
-
MemoryTransportFactory: () => MemoryTransportFactory,
|
|
41
|
-
RtcTransportProxy: () => RtcTransportProxy,
|
|
42
|
-
RtcTransportProxyFactory: () => RtcTransportProxyFactory,
|
|
43
|
-
RtcTransportService: () => RtcTransportService,
|
|
44
|
-
StarTopology: () => StarTopology,
|
|
45
|
-
Swarm: () => Swarm,
|
|
46
|
-
SwarmMapper: () => SwarmMapper,
|
|
47
|
-
SwarmMessenger: () => SwarmMessenger,
|
|
48
|
-
SwarmNetworkManager: () => SwarmNetworkManager,
|
|
49
|
-
TransportKind: () => TransportKind,
|
|
50
|
-
createIceProvider: () => createIceProvider,
|
|
51
|
-
createRtcTransportFactory: () => createRtcTransportFactory,
|
|
52
|
-
createTeleportProtocolFactory: () => createTeleportProtocolFactory
|
|
53
|
-
});
|
|
54
|
-
module.exports = __toCommonJS(chunk_2G6RZMS5_exports);
|
|
55
|
-
var import_async = require("@dxos/async");
|
|
56
|
-
var import_context = require("@dxos/context");
|
|
57
|
-
var import_debug = require("@dxos/debug");
|
|
58
|
-
var import_invariant = require("@dxos/invariant");
|
|
59
|
-
var import_keys = require("@dxos/keys");
|
|
60
|
-
var import_log = require("@dxos/log");
|
|
61
|
-
var import_protocols = require("@dxos/protocols");
|
|
62
|
-
var import_async2 = require("@dxos/async");
|
|
63
|
-
var import_log2 = require("@dxos/log");
|
|
64
|
-
var import_util = require("@dxos/util");
|
|
65
|
-
var import_context2 = require("@dxos/context");
|
|
66
|
-
var import_invariant2 = require("@dxos/invariant");
|
|
67
|
-
var import_keys2 = require("@dxos/keys");
|
|
68
|
-
var import_log3 = require("@dxos/log");
|
|
69
|
-
var import_protocols2 = require("@dxos/protocols");
|
|
70
|
-
var import_proto = require("@dxos/protocols/proto");
|
|
71
|
-
var import_util2 = require("@dxos/util");
|
|
72
|
-
var import_async3 = require("@dxos/async");
|
|
73
|
-
var import_context3 = require("@dxos/context");
|
|
74
|
-
var import_debug2 = require("@dxos/debug");
|
|
75
|
-
var import_invariant3 = require("@dxos/invariant");
|
|
76
|
-
var import_keys3 = require("@dxos/keys");
|
|
77
|
-
var import_log4 = require("@dxos/log");
|
|
78
|
-
var import_messaging = require("@dxos/messaging");
|
|
79
|
-
var import_protocols3 = require("@dxos/protocols");
|
|
80
|
-
var import_util3 = require("@dxos/util");
|
|
81
|
-
var import_async4 = require("@dxos/async");
|
|
82
|
-
var import_context4 = require("@dxos/context");
|
|
83
|
-
var import_invariant4 = require("@dxos/invariant");
|
|
84
|
-
var import_keys4 = require("@dxos/keys");
|
|
85
|
-
var import_log5 = require("@dxos/log");
|
|
86
|
-
var import_protocols4 = require("@dxos/protocols");
|
|
87
|
-
var import_async5 = require("@dxos/async");
|
|
88
|
-
var import_keys5 = require("@dxos/keys");
|
|
89
|
-
var import_log6 = require("@dxos/log");
|
|
90
|
-
var import_messaging2 = require("@dxos/messaging");
|
|
91
|
-
var import_util4 = require("@dxos/util");
|
|
92
|
-
var import_async6 = require("@dxos/async");
|
|
93
|
-
var import_context5 = require("@dxos/context");
|
|
94
|
-
var import_invariant5 = require("@dxos/invariant");
|
|
95
|
-
var import_keys6 = require("@dxos/keys");
|
|
96
|
-
var import_log7 = require("@dxos/log");
|
|
97
|
-
var import_protocols5 = require("@dxos/protocols");
|
|
98
|
-
var import_util5 = require("@dxos/util");
|
|
99
|
-
var import_async7 = require("@dxos/async");
|
|
100
|
-
var import_debug3 = require("@dxos/debug");
|
|
101
|
-
var import_keys7 = require("@dxos/keys");
|
|
102
|
-
var import_util6 = require("@dxos/util");
|
|
103
|
-
var import_async8 = require("@dxos/async");
|
|
104
|
-
var import_invariant6 = require("@dxos/invariant");
|
|
105
|
-
var import_keys8 = require("@dxos/keys");
|
|
106
|
-
var import_log8 = require("@dxos/log");
|
|
107
|
-
var import_messaging3 = require("@dxos/messaging");
|
|
108
|
-
var import_protocols6 = require("@dxos/protocols");
|
|
109
|
-
var import_services = require("@dxos/protocols/proto/dxos/client/services");
|
|
110
|
-
var import_util7 = require("@dxos/util");
|
|
111
|
-
var import_invariant7 = require("@dxos/invariant");
|
|
112
|
-
var import_invariant8 = require("@dxos/invariant");
|
|
113
|
-
var import_log9 = require("@dxos/log");
|
|
114
|
-
var import_invariant9 = require("@dxos/invariant");
|
|
115
|
-
var import_log10 = require("@dxos/log");
|
|
116
|
-
var import_node_stream = require("node:stream");
|
|
117
|
-
var import_async9 = require("@dxos/async");
|
|
118
|
-
var import_debug4 = require("@dxos/debug");
|
|
119
|
-
var import_invariant10 = require("@dxos/invariant");
|
|
120
|
-
var import_keys9 = require("@dxos/keys");
|
|
121
|
-
var import_log11 = require("@dxos/log");
|
|
122
|
-
var import_util8 = require("@dxos/util");
|
|
123
|
-
var import_async10 = require("@dxos/async");
|
|
124
|
-
var import_async11 = require("@dxos/async");
|
|
125
|
-
var import_invariant11 = require("@dxos/invariant");
|
|
126
|
-
var import_log12 = require("@dxos/log");
|
|
127
|
-
var import_protocols7 = require("@dxos/protocols");
|
|
128
|
-
var import_tracing = require("@dxos/tracing");
|
|
129
|
-
var import_node_stream2 = require("node:stream");
|
|
130
|
-
var import_async12 = require("@dxos/async");
|
|
131
|
-
var import_context6 = require("@dxos/context");
|
|
132
|
-
var import_debug5 = require("@dxos/debug");
|
|
133
|
-
var import_invariant12 = require("@dxos/invariant");
|
|
134
|
-
var import_log13 = require("@dxos/log");
|
|
135
|
-
var import_protocols8 = require("@dxos/protocols");
|
|
136
|
-
var import_node_stream3 = require("node:stream");
|
|
137
|
-
var import_async13 = require("@dxos/async");
|
|
138
|
-
var import_context7 = require("@dxos/context");
|
|
139
|
-
var import_debug6 = require("@dxos/debug");
|
|
140
|
-
var import_invariant13 = require("@dxos/invariant");
|
|
141
|
-
var import_keys10 = require("@dxos/keys");
|
|
142
|
-
var import_log14 = require("@dxos/log");
|
|
143
|
-
var import_protocols9 = require("@dxos/protocols");
|
|
144
|
-
var import_bridge = require("@dxos/protocols/proto/dxos/mesh/bridge");
|
|
145
|
-
var import_util9 = require("@dxos/util");
|
|
146
|
-
var import_node_stream4 = require("node:stream");
|
|
147
|
-
var import_stream = require("@dxos/codec-protobuf/stream");
|
|
148
|
-
var import_invariant14 = require("@dxos/invariant");
|
|
149
|
-
var import_keys11 = require("@dxos/keys");
|
|
150
|
-
var import_log15 = require("@dxos/log");
|
|
151
|
-
var import_bridge2 = require("@dxos/protocols/proto/dxos/mesh/bridge");
|
|
152
|
-
var import_util10 = require("@dxos/util");
|
|
153
|
-
var import_teleport = require("@dxos/teleport");
|
|
154
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
155
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
156
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
157
|
-
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;
|
|
158
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
159
|
-
}
|
|
160
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/swarm/connection.ts";
|
|
161
|
-
var STARTING_SIGNALLING_DELAY = 10;
|
|
162
|
-
var TRANSPORT_CONNECTION_TIMEOUT = 1e4;
|
|
163
|
-
var TRANSPORT_STATS_INTERVAL = 5e3;
|
|
164
|
-
var MAX_SIGNALLING_DELAY = 300;
|
|
165
|
-
var ConnectionState = /* @__PURE__ */ function(ConnectionState5) {
|
|
166
|
-
ConnectionState5["CREATED"] = "CREATED";
|
|
167
|
-
ConnectionState5["INITIAL"] = "INITIAL";
|
|
168
|
-
ConnectionState5["CONNECTING"] = "CONNECTING";
|
|
169
|
-
ConnectionState5["CONNECTED"] = "CONNECTED";
|
|
170
|
-
ConnectionState5["CLOSING"] = "CLOSING";
|
|
171
|
-
ConnectionState5["CLOSED"] = "CLOSED";
|
|
172
|
-
ConnectionState5["ABORTING"] = "ABORTING";
|
|
173
|
-
ConnectionState5["ABORTED"] = "ABORTED";
|
|
174
|
-
return ConnectionState5;
|
|
175
|
-
}({});
|
|
176
|
-
var Connection = class {
|
|
177
|
-
constructor(topic, localInfo, remoteInfo, sessionId, initiator, _signalMessaging, _protocol, _transportFactory, _callbacks) {
|
|
178
|
-
this.topic = topic;
|
|
179
|
-
this.localInfo = localInfo;
|
|
180
|
-
this.remoteInfo = remoteInfo;
|
|
181
|
-
this.sessionId = sessionId;
|
|
182
|
-
this.initiator = initiator;
|
|
183
|
-
this._signalMessaging = _signalMessaging;
|
|
184
|
-
this._protocol = _protocol;
|
|
185
|
-
this._transportFactory = _transportFactory;
|
|
186
|
-
this._callbacks = _callbacks;
|
|
187
|
-
this._ctx = new import_context.Context(void 0, {
|
|
188
|
-
F: __dxlog_file,
|
|
189
|
-
L: 100
|
|
190
|
-
});
|
|
191
|
-
this.connectedTimeoutContext = new import_context.Context(void 0, {
|
|
192
|
-
F: __dxlog_file,
|
|
193
|
-
L: 101
|
|
194
|
-
});
|
|
195
|
-
this._protocolClosed = new import_async.Trigger();
|
|
196
|
-
this._transportClosed = new import_async.Trigger();
|
|
197
|
-
this._state = "CREATED";
|
|
198
|
-
this._incomingSignalBuffer = [];
|
|
199
|
-
this._outgoingSignalBuffer = [];
|
|
200
|
-
this.stateChanged = new import_async.Event();
|
|
201
|
-
this.errors = new import_debug.ErrorStream();
|
|
202
|
-
this._instanceId = import_keys.PublicKey.random().toHex();
|
|
203
|
-
this.transportStats = new import_async.Event();
|
|
204
|
-
this._signalSendTask = new import_async.DeferredTask(this._ctx, async () => {
|
|
205
|
-
await this._flushSignalBuffer();
|
|
206
|
-
});
|
|
207
|
-
this._signallingDelay = STARTING_SIGNALLING_DELAY;
|
|
208
|
-
import_log.log.trace("dxos.mesh.connection.construct", {
|
|
209
|
-
sessionId: this.sessionId,
|
|
210
|
-
topic: this.topic,
|
|
211
|
-
localPeer: this.localInfo,
|
|
212
|
-
remotePeer: this.remoteInfo,
|
|
213
|
-
initiator: this.initiator
|
|
214
|
-
}, {
|
|
215
|
-
F: __dxlog_file,
|
|
216
|
-
L: 137,
|
|
217
|
-
S: this,
|
|
218
|
-
C: (f, a) => f(...a)
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
get sessionIdString() {
|
|
222
|
-
return this.sessionId.truncate();
|
|
223
|
-
}
|
|
224
|
-
get state() {
|
|
225
|
-
return this._state;
|
|
226
|
-
}
|
|
227
|
-
get transport() {
|
|
228
|
-
return this._transport;
|
|
229
|
-
}
|
|
230
|
-
get protocol() {
|
|
231
|
-
return this._protocol;
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Create an underlying transport and prepares it for the connection.
|
|
235
|
-
*/
|
|
236
|
-
async openConnection() {
|
|
237
|
-
(0, import_invariant.invariant)(this._state === "INITIAL", "Invalid state.", {
|
|
238
|
-
F: __dxlog_file,
|
|
239
|
-
L: 167,
|
|
240
|
-
S: this,
|
|
241
|
-
A: [
|
|
242
|
-
"this._state === ConnectionState.INITIAL",
|
|
243
|
-
"'Invalid state.'"
|
|
244
|
-
]
|
|
245
|
-
});
|
|
246
|
-
import_log.log.trace("dxos.mesh.connection.open-connection", import_protocols.trace.begin({
|
|
247
|
-
id: this._instanceId
|
|
248
|
-
}), {
|
|
249
|
-
F: __dxlog_file,
|
|
250
|
-
L: 168,
|
|
251
|
-
S: this,
|
|
252
|
-
C: (f, a) => f(...a)
|
|
253
|
-
});
|
|
254
|
-
import_log.log.trace("dxos.mesh.connection.open", {
|
|
255
|
-
sessionId: this.sessionId,
|
|
256
|
-
topic: this.topic,
|
|
257
|
-
localPeerId: this.localInfo,
|
|
258
|
-
remotePeerId: this.remoteInfo,
|
|
259
|
-
initiator: this.initiator
|
|
260
|
-
}, {
|
|
261
|
-
F: __dxlog_file,
|
|
262
|
-
L: 169,
|
|
263
|
-
S: this,
|
|
264
|
-
C: (f, a) => f(...a)
|
|
265
|
-
});
|
|
266
|
-
this._changeState("CONNECTING");
|
|
267
|
-
this._protocol.open(this.sessionId).catch((err) => {
|
|
268
|
-
this.errors.raise(err);
|
|
269
|
-
});
|
|
270
|
-
this._protocol.stream.on("close", () => {
|
|
271
|
-
(0, import_log.log)("protocol stream closed", void 0, {
|
|
272
|
-
F: __dxlog_file,
|
|
273
|
-
L: 186,
|
|
274
|
-
S: this,
|
|
275
|
-
C: (f, a) => f(...a)
|
|
276
|
-
});
|
|
277
|
-
this._protocolClosed.wake();
|
|
278
|
-
this.close({
|
|
279
|
-
error: new import_protocols.ProtocolError("protocol stream closed")
|
|
280
|
-
}).catch((err) => this.errors.raise(err));
|
|
281
|
-
});
|
|
282
|
-
(0, import_async.scheduleTask)(this.connectedTimeoutContext, async () => {
|
|
283
|
-
import_log.log.info(`timeout waiting ${TRANSPORT_CONNECTION_TIMEOUT / 1e3}s for transport to connect, aborting`, void 0, {
|
|
284
|
-
F: __dxlog_file,
|
|
285
|
-
L: 194,
|
|
286
|
-
S: this,
|
|
287
|
-
C: (f, a) => f(...a)
|
|
288
|
-
});
|
|
289
|
-
await this.abort(new import_protocols.TimeoutError(`${TRANSPORT_CONNECTION_TIMEOUT / 1e3}s for transport to connect`)).catch((err) => this.errors.raise(err));
|
|
290
|
-
}, TRANSPORT_CONNECTION_TIMEOUT);
|
|
291
|
-
(0, import_invariant.invariant)(!this._transport, void 0, {
|
|
292
|
-
F: __dxlog_file,
|
|
293
|
-
L: 202,
|
|
294
|
-
S: this,
|
|
295
|
-
A: [
|
|
296
|
-
"!this._transport",
|
|
297
|
-
""
|
|
298
|
-
]
|
|
299
|
-
});
|
|
300
|
-
this._transport = this._transportFactory.createTransport({
|
|
301
|
-
ownPeerKey: this.localInfo.peerKey,
|
|
302
|
-
remotePeerKey: this.remoteInfo.peerKey,
|
|
303
|
-
topic: this.topic.toHex(),
|
|
304
|
-
initiator: this.initiator,
|
|
305
|
-
stream: this._protocol.stream,
|
|
306
|
-
sendSignal: async (signal) => this._sendSignal(signal),
|
|
307
|
-
sessionId: this.sessionId
|
|
308
|
-
});
|
|
309
|
-
this._transport.connected.once(async () => {
|
|
310
|
-
this._changeState("CONNECTED");
|
|
311
|
-
await this.connectedTimeoutContext.dispose();
|
|
312
|
-
this._callbacks?.onConnected?.();
|
|
313
|
-
(0, import_async.scheduleTaskInterval)(this._ctx, async () => this._emitTransportStats(), TRANSPORT_STATS_INTERVAL);
|
|
314
|
-
});
|
|
315
|
-
this._transport.closed.once(() => {
|
|
316
|
-
this._transport = void 0;
|
|
317
|
-
this._transportClosed.wake();
|
|
318
|
-
(0, import_log.log)("abort triggered by transport close", void 0, {
|
|
319
|
-
F: __dxlog_file,
|
|
320
|
-
L: 224,
|
|
321
|
-
S: this,
|
|
322
|
-
C: (f, a) => f(...a)
|
|
323
|
-
});
|
|
324
|
-
this.abort().catch((err) => this.errors.raise(err));
|
|
325
|
-
});
|
|
326
|
-
this._transport.errors.handle(async (err) => {
|
|
327
|
-
(0, import_log.log)("transport error:", {
|
|
328
|
-
err
|
|
329
|
-
}, {
|
|
330
|
-
F: __dxlog_file,
|
|
331
|
-
L: 229,
|
|
332
|
-
S: this,
|
|
333
|
-
C: (f, a) => f(...a)
|
|
334
|
-
});
|
|
335
|
-
if (!this.closeReason) {
|
|
336
|
-
this.closeReason = err?.message;
|
|
337
|
-
}
|
|
338
|
-
if (err instanceof import_protocols.ConnectionResetError) {
|
|
339
|
-
import_log.log.info("aborting due to transport ConnectionResetError", void 0, {
|
|
340
|
-
F: __dxlog_file,
|
|
341
|
-
L: 236,
|
|
342
|
-
S: this,
|
|
343
|
-
C: (f, a) => f(...a)
|
|
344
|
-
});
|
|
345
|
-
this.abort(err).catch((err2) => this.errors.raise(err2));
|
|
346
|
-
} else if (err instanceof import_protocols.ConnectivityError) {
|
|
347
|
-
import_log.log.info("aborting due to transport ConnectivityError", void 0, {
|
|
348
|
-
F: __dxlog_file,
|
|
349
|
-
L: 239,
|
|
350
|
-
S: this,
|
|
351
|
-
C: (f, a) => f(...a)
|
|
352
|
-
});
|
|
353
|
-
this.abort(err).catch((err2) => this.errors.raise(err2));
|
|
354
|
-
}
|
|
355
|
-
if (this._state !== "CLOSED" && this._state !== "CLOSING") {
|
|
356
|
-
await this.connectedTimeoutContext.dispose();
|
|
357
|
-
this.errors.raise(err);
|
|
358
|
-
}
|
|
359
|
-
});
|
|
360
|
-
await this._transport.open();
|
|
361
|
-
for (const signal of this._incomingSignalBuffer) {
|
|
362
|
-
void this._transport.onSignal(signal);
|
|
363
|
-
}
|
|
364
|
-
this._incomingSignalBuffer = [];
|
|
365
|
-
import_log.log.trace("dxos.mesh.connection.open-connection", import_protocols.trace.end({
|
|
366
|
-
id: this._instanceId
|
|
367
|
-
}), {
|
|
368
|
-
F: __dxlog_file,
|
|
369
|
-
L: 258,
|
|
370
|
-
S: this,
|
|
371
|
-
C: (f, a) => f(...a)
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
async abort(err) {
|
|
375
|
-
(0, import_log.log)("abort", {
|
|
376
|
-
err
|
|
377
|
-
}, {
|
|
378
|
-
F: __dxlog_file,
|
|
379
|
-
L: 265,
|
|
380
|
-
S: this,
|
|
381
|
-
C: (f, a) => f(...a)
|
|
382
|
-
});
|
|
383
|
-
if (this._state === "CLOSED" || this._state === "ABORTED") {
|
|
384
|
-
(0, import_log.log)(`abort ignored: already ${this._state}`, this.closeReason, {
|
|
385
|
-
F: __dxlog_file,
|
|
386
|
-
L: 267,
|
|
387
|
-
S: this,
|
|
388
|
-
C: (f, a) => f(...a)
|
|
389
|
-
});
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
await this.connectedTimeoutContext.dispose();
|
|
393
|
-
this._changeState("ABORTING");
|
|
394
|
-
if (!this.closeReason) {
|
|
395
|
-
this.closeReason = err?.message;
|
|
396
|
-
}
|
|
397
|
-
await this._ctx.dispose();
|
|
398
|
-
(0, import_log.log)("aborting...", {
|
|
399
|
-
peerId: this.localInfo,
|
|
400
|
-
err
|
|
401
|
-
}, {
|
|
402
|
-
F: __dxlog_file,
|
|
403
|
-
L: 279,
|
|
404
|
-
S: this,
|
|
405
|
-
C: (f, a) => f(...a)
|
|
406
|
-
});
|
|
407
|
-
try {
|
|
408
|
-
await this._closeProtocol({
|
|
409
|
-
abort: true
|
|
410
|
-
});
|
|
411
|
-
} catch (err2) {
|
|
412
|
-
import_log.log.catch(err2, void 0, {
|
|
413
|
-
F: __dxlog_file,
|
|
414
|
-
L: 285,
|
|
415
|
-
S: this,
|
|
416
|
-
C: (f, a) => f(...a)
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
try {
|
|
420
|
-
await this._closeTransport();
|
|
421
|
-
} catch (err2) {
|
|
422
|
-
import_log.log.catch(err2, void 0, {
|
|
423
|
-
F: __dxlog_file,
|
|
424
|
-
L: 292,
|
|
425
|
-
S: this,
|
|
426
|
-
C: (f, a) => f(...a)
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
|
-
try {
|
|
430
|
-
this._callbacks?.onClosed?.(err);
|
|
431
|
-
} catch (err2) {
|
|
432
|
-
import_log.log.catch(err2, void 0, {
|
|
433
|
-
F: __dxlog_file,
|
|
434
|
-
L: 298,
|
|
435
|
-
S: this,
|
|
436
|
-
C: (f, a) => f(...a)
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
this._changeState("ABORTED");
|
|
440
|
-
}
|
|
441
|
-
async close({ error, reason } = {}) {
|
|
442
|
-
(0, import_log.log)("close", {
|
|
443
|
-
error
|
|
444
|
-
}, {
|
|
445
|
-
F: __dxlog_file,
|
|
446
|
-
L: 305,
|
|
447
|
-
S: this,
|
|
448
|
-
C: (f, a) => f(...a)
|
|
449
|
-
});
|
|
450
|
-
if (!this.closeReason) {
|
|
451
|
-
this.closeReason = reason ?? error?.message;
|
|
452
|
-
} else {
|
|
453
|
-
this.closeReason += `; ${reason ?? error?.message}`;
|
|
454
|
-
}
|
|
455
|
-
if (this._state === "CLOSED" || this._state === "ABORTING" || this._state === "ABORTED") {
|
|
456
|
-
(0, import_log.log)("close ignored: already in progress", {
|
|
457
|
-
state: this._state,
|
|
458
|
-
error
|
|
459
|
-
}, {
|
|
460
|
-
F: __dxlog_file,
|
|
461
|
-
L: 316,
|
|
462
|
-
S: this,
|
|
463
|
-
C: (f, a) => f(...a)
|
|
464
|
-
});
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
const lastState = this._state;
|
|
468
|
-
this._changeState("CLOSING");
|
|
469
|
-
await this.connectedTimeoutContext.dispose();
|
|
470
|
-
await this._ctx.dispose();
|
|
471
|
-
let abortProtocol = false;
|
|
472
|
-
if (lastState !== "CONNECTED" || error != null) {
|
|
473
|
-
(0, import_log.log)(`graceful close requested when we were in ${lastState} state? aborting`, void 0, {
|
|
474
|
-
F: __dxlog_file,
|
|
475
|
-
L: 327,
|
|
476
|
-
S: this,
|
|
477
|
-
C: (f, a) => f(...a)
|
|
478
|
-
});
|
|
479
|
-
abortProtocol = true;
|
|
480
|
-
}
|
|
481
|
-
(0, import_log.log)("closing...", {
|
|
482
|
-
peerId: this.localInfo,
|
|
483
|
-
abortProtocol,
|
|
484
|
-
error
|
|
485
|
-
}, {
|
|
486
|
-
F: __dxlog_file,
|
|
487
|
-
L: 331,
|
|
488
|
-
S: this,
|
|
489
|
-
C: (f, a) => f(...a)
|
|
490
|
-
});
|
|
491
|
-
try {
|
|
492
|
-
await this._closeProtocol({
|
|
493
|
-
abort: abortProtocol
|
|
494
|
-
});
|
|
495
|
-
} catch (err) {
|
|
496
|
-
import_log.log.catch(err, void 0, {
|
|
497
|
-
F: __dxlog_file,
|
|
498
|
-
L: 336,
|
|
499
|
-
S: this,
|
|
500
|
-
C: (f, a) => f(...a)
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
try {
|
|
504
|
-
await this._closeTransport();
|
|
505
|
-
} catch (err) {
|
|
506
|
-
import_log.log.catch(err, void 0, {
|
|
507
|
-
F: __dxlog_file,
|
|
508
|
-
L: 342,
|
|
509
|
-
S: this,
|
|
510
|
-
C: (f, a) => f(...a)
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
(0, import_log.log)("closed", {
|
|
514
|
-
peerId: this.localInfo
|
|
515
|
-
}, {
|
|
516
|
-
F: __dxlog_file,
|
|
517
|
-
L: 345,
|
|
518
|
-
S: this,
|
|
519
|
-
C: (f, a) => f(...a)
|
|
520
|
-
});
|
|
521
|
-
this._changeState("CLOSED");
|
|
522
|
-
this._callbacks?.onClosed?.(error);
|
|
523
|
-
}
|
|
524
|
-
async _closeProtocol(options) {
|
|
525
|
-
(0, import_log.log)("closing protocol", options, {
|
|
526
|
-
F: __dxlog_file,
|
|
527
|
-
L: 351,
|
|
528
|
-
S: this,
|
|
529
|
-
C: (f, a) => f(...a)
|
|
530
|
-
});
|
|
531
|
-
await Promise.race([
|
|
532
|
-
options?.abort ? this._protocol.abort() : this._protocol.close(),
|
|
533
|
-
this._protocolClosed.wait()
|
|
534
|
-
]);
|
|
535
|
-
(0, import_log.log)("protocol closed", options, {
|
|
536
|
-
F: __dxlog_file,
|
|
537
|
-
L: 353,
|
|
538
|
-
S: this,
|
|
539
|
-
C: (f, a) => f(...a)
|
|
540
|
-
});
|
|
541
|
-
}
|
|
542
|
-
async _closeTransport() {
|
|
543
|
-
(0, import_log.log)("closing transport", void 0, {
|
|
544
|
-
F: __dxlog_file,
|
|
545
|
-
L: 357,
|
|
546
|
-
S: this,
|
|
547
|
-
C: (f, a) => f(...a)
|
|
548
|
-
});
|
|
549
|
-
await Promise.race([
|
|
550
|
-
this._transport?.close(),
|
|
551
|
-
this._transportClosed.wait()
|
|
552
|
-
]);
|
|
553
|
-
(0, import_log.log)("transport closed", void 0, {
|
|
554
|
-
F: __dxlog_file,
|
|
555
|
-
L: 359,
|
|
556
|
-
S: this,
|
|
557
|
-
C: (f, a) => f(...a)
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
_sendSignal(signal) {
|
|
561
|
-
this._outgoingSignalBuffer.push(signal);
|
|
562
|
-
this._signalSendTask.schedule();
|
|
563
|
-
}
|
|
564
|
-
async _flushSignalBuffer() {
|
|
565
|
-
if (this._outgoingSignalBuffer.length === 0) {
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
try {
|
|
569
|
-
if (process.env.NODE_ENV !== "test") {
|
|
570
|
-
await (0, import_context.cancelWithContext)(this._ctx, (0, import_async.sleep)(this._signallingDelay));
|
|
571
|
-
this._signallingDelay = Math.min(this._signallingDelay * 2, MAX_SIGNALLING_DELAY);
|
|
572
|
-
}
|
|
573
|
-
const signals = [
|
|
574
|
-
...this._outgoingSignalBuffer
|
|
575
|
-
];
|
|
576
|
-
this._outgoingSignalBuffer.length = 0;
|
|
577
|
-
await this._signalMessaging.signal({
|
|
578
|
-
author: this.localInfo,
|
|
579
|
-
recipient: this.remoteInfo,
|
|
580
|
-
sessionId: this.sessionId,
|
|
581
|
-
topic: this.topic,
|
|
582
|
-
data: {
|
|
583
|
-
signalBatch: {
|
|
584
|
-
signals
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
});
|
|
588
|
-
} catch (err) {
|
|
589
|
-
if (err instanceof import_protocols.CancelledError || err instanceof import_context.ContextDisposedError || err instanceof Error && err.message?.includes("CANCELLED")) {
|
|
590
|
-
return;
|
|
591
|
-
}
|
|
592
|
-
import_log.log.info("signal message failed to deliver", {
|
|
593
|
-
err
|
|
594
|
-
}, {
|
|
595
|
-
F: __dxlog_file,
|
|
596
|
-
L: 399,
|
|
597
|
-
S: this,
|
|
598
|
-
C: (f, a) => f(...a)
|
|
599
|
-
});
|
|
600
|
-
await this.close({
|
|
601
|
-
error: new import_protocols.ConnectivityError("signal message failed to deliver", err)
|
|
602
|
-
});
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
/**
|
|
606
|
-
* Receive a signal from the remote peer.
|
|
607
|
-
*/
|
|
608
|
-
async signal(msg) {
|
|
609
|
-
(0, import_invariant.invariant)(msg.sessionId, void 0, {
|
|
610
|
-
F: __dxlog_file,
|
|
611
|
-
L: 408,
|
|
612
|
-
S: this,
|
|
613
|
-
A: [
|
|
614
|
-
"msg.sessionId",
|
|
615
|
-
""
|
|
616
|
-
]
|
|
617
|
-
});
|
|
618
|
-
if (!msg.sessionId.equals(this.sessionId)) {
|
|
619
|
-
(0, import_log.log)("dropping signal for incorrect session id", void 0, {
|
|
620
|
-
F: __dxlog_file,
|
|
621
|
-
L: 410,
|
|
622
|
-
S: this,
|
|
623
|
-
C: (f, a) => f(...a)
|
|
624
|
-
});
|
|
625
|
-
return;
|
|
626
|
-
}
|
|
627
|
-
(0, import_invariant.invariant)(msg.data.signal || msg.data.signalBatch, void 0, {
|
|
628
|
-
F: __dxlog_file,
|
|
629
|
-
L: 413,
|
|
630
|
-
S: this,
|
|
631
|
-
A: [
|
|
632
|
-
"msg.data.signal || msg.data.signalBatch",
|
|
633
|
-
""
|
|
634
|
-
]
|
|
635
|
-
});
|
|
636
|
-
(0, import_invariant.invariant)(msg.author.peerKey === this.remoteInfo.peerKey, void 0, {
|
|
637
|
-
F: __dxlog_file,
|
|
638
|
-
L: 414,
|
|
639
|
-
S: this,
|
|
640
|
-
A: [
|
|
641
|
-
"msg.author.peerKey === this.remoteInfo.peerKey",
|
|
642
|
-
""
|
|
643
|
-
]
|
|
644
|
-
});
|
|
645
|
-
(0, import_invariant.invariant)(msg.recipient.peerKey === this.localInfo.peerKey, void 0, {
|
|
646
|
-
F: __dxlog_file,
|
|
647
|
-
L: 415,
|
|
648
|
-
S: this,
|
|
649
|
-
A: [
|
|
650
|
-
"msg.recipient.peerKey === this.localInfo.peerKey",
|
|
651
|
-
""
|
|
652
|
-
]
|
|
653
|
-
});
|
|
654
|
-
const signals = msg.data.signalBatch ? msg.data.signalBatch.signals ?? [] : [
|
|
655
|
-
msg.data.signal
|
|
656
|
-
];
|
|
657
|
-
for (const signal of signals) {
|
|
658
|
-
if (!signal) {
|
|
659
|
-
continue;
|
|
660
|
-
}
|
|
661
|
-
if ([
|
|
662
|
-
"CREATED",
|
|
663
|
-
"INITIAL"
|
|
664
|
-
].includes(this.state)) {
|
|
665
|
-
(0, import_log.log)("buffered signal", {
|
|
666
|
-
peerId: this.localInfo,
|
|
667
|
-
remoteId: this.remoteInfo,
|
|
668
|
-
msg: msg.data
|
|
669
|
-
}, {
|
|
670
|
-
F: __dxlog_file,
|
|
671
|
-
L: 424,
|
|
672
|
-
S: this,
|
|
673
|
-
C: (f, a) => f(...a)
|
|
674
|
-
});
|
|
675
|
-
this._incomingSignalBuffer.push(signal);
|
|
676
|
-
} else {
|
|
677
|
-
(0, import_invariant.invariant)(this._transport, "Connection not ready to accept signals.", {
|
|
678
|
-
F: __dxlog_file,
|
|
679
|
-
L: 427,
|
|
680
|
-
S: this,
|
|
681
|
-
A: [
|
|
682
|
-
"this._transport",
|
|
683
|
-
"'Connection not ready to accept signals.'"
|
|
684
|
-
]
|
|
685
|
-
});
|
|
686
|
-
(0, import_log.log)("received signal", {
|
|
687
|
-
peerId: this.localInfo,
|
|
688
|
-
remoteId: this.remoteInfo,
|
|
689
|
-
msg: msg.data
|
|
690
|
-
}, {
|
|
691
|
-
F: __dxlog_file,
|
|
692
|
-
L: 428,
|
|
693
|
-
S: this,
|
|
694
|
-
C: (f, a) => f(...a)
|
|
695
|
-
});
|
|
696
|
-
await this._transport.onSignal(signal);
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
initiate() {
|
|
701
|
-
this._changeState("INITIAL");
|
|
702
|
-
}
|
|
703
|
-
_changeState(state) {
|
|
704
|
-
(0, import_log.log)("stateChanged", {
|
|
705
|
-
from: this._state,
|
|
706
|
-
to: state,
|
|
707
|
-
peerId: this.localInfo
|
|
708
|
-
}, {
|
|
709
|
-
F: __dxlog_file,
|
|
710
|
-
L: 439,
|
|
711
|
-
S: this,
|
|
712
|
-
C: (f, a) => f(...a)
|
|
713
|
-
});
|
|
714
|
-
(0, import_invariant.invariant)(state !== this._state, "Already in this state.", {
|
|
715
|
-
F: __dxlog_file,
|
|
716
|
-
L: 440,
|
|
717
|
-
S: this,
|
|
718
|
-
A: [
|
|
719
|
-
"state !== this._state",
|
|
720
|
-
"'Already in this state.'"
|
|
721
|
-
]
|
|
722
|
-
});
|
|
723
|
-
this._state = state;
|
|
724
|
-
this.stateChanged.emit(state);
|
|
725
|
-
}
|
|
726
|
-
async _emitTransportStats() {
|
|
727
|
-
const stats = await this.transport?.getStats();
|
|
728
|
-
if (stats) {
|
|
729
|
-
this.transportStats.emit(stats);
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
};
|
|
733
|
-
_ts_decorate([
|
|
734
|
-
import_log.logInfo
|
|
735
|
-
], Connection.prototype, "sessionIdString", null);
|
|
736
|
-
_ts_decorate([
|
|
737
|
-
import_async.synchronized
|
|
738
|
-
], Connection.prototype, "abort", null);
|
|
739
|
-
_ts_decorate([
|
|
740
|
-
import_async.synchronized
|
|
741
|
-
], Connection.prototype, "close", null);
|
|
742
|
-
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/signal/ice.ts";
|
|
743
|
-
var createIceProvider = (iceProviders) => {
|
|
744
|
-
let cachedIceServers;
|
|
745
|
-
return {
|
|
746
|
-
getIceServers: async () => {
|
|
747
|
-
if (cachedIceServers) {
|
|
748
|
-
return cachedIceServers;
|
|
749
|
-
}
|
|
750
|
-
cachedIceServers = (await Promise.all(iceProviders.map(({ urls }) => (0, import_async2.asyncTimeout)(fetch(urls, {
|
|
751
|
-
method: "GET"
|
|
752
|
-
}), 1e4).then((response) => response.json()).catch((err) => {
|
|
753
|
-
const isDev = typeof window !== "undefined" && window.location.href.includes("localhost");
|
|
754
|
-
if (!isDev) {
|
|
755
|
-
import_log2.log.error("Failed to fetch ICE servers from provider", {
|
|
756
|
-
urls,
|
|
757
|
-
err
|
|
758
|
-
}, {
|
|
759
|
-
F: __dxlog_file2,
|
|
760
|
-
L: 30,
|
|
761
|
-
S: void 0,
|
|
762
|
-
C: (f, a) => f(...a)
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
})))).filter(import_util.isNonNullable).map(({ iceServers }) => iceServers).flat();
|
|
766
|
-
return cachedIceServers;
|
|
767
|
-
}
|
|
768
|
-
};
|
|
769
|
-
};
|
|
770
|
-
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/signal/swarm-messenger.ts";
|
|
771
|
-
var SwarmMessage = import_proto.schema.getCodecForType("dxos.mesh.swarm.SwarmMessage");
|
|
772
|
-
var SwarmMessenger = class {
|
|
773
|
-
constructor({ sendMessage, onSignal, onOffer, topic }) {
|
|
774
|
-
this._ctx = new import_context2.Context(void 0, {
|
|
775
|
-
F: __dxlog_file3,
|
|
776
|
-
L: 35
|
|
777
|
-
});
|
|
778
|
-
this._offerRecords = new import_util2.ComplexMap((key) => key.toHex());
|
|
779
|
-
this._sendMessage = sendMessage;
|
|
780
|
-
this._onSignal = onSignal;
|
|
781
|
-
this._onOffer = onOffer;
|
|
782
|
-
this._topic = topic;
|
|
783
|
-
}
|
|
784
|
-
async receiveMessage({ author, recipient, payload }) {
|
|
785
|
-
if (payload.type_url !== "dxos.mesh.swarm.SwarmMessage") {
|
|
786
|
-
return;
|
|
787
|
-
}
|
|
788
|
-
const message = SwarmMessage.decode(payload.value);
|
|
789
|
-
if (!this._topic.equals(message.topic)) {
|
|
790
|
-
return;
|
|
791
|
-
}
|
|
792
|
-
(0, import_log3.log)("received", {
|
|
793
|
-
from: author,
|
|
794
|
-
to: recipient,
|
|
795
|
-
msg: message
|
|
796
|
-
}, {
|
|
797
|
-
F: __dxlog_file3,
|
|
798
|
-
L: 71,
|
|
799
|
-
S: this,
|
|
800
|
-
C: (f, a) => f(...a)
|
|
801
|
-
});
|
|
802
|
-
if (message.data?.offer) {
|
|
803
|
-
await this._handleOffer({
|
|
804
|
-
author,
|
|
805
|
-
recipient,
|
|
806
|
-
message
|
|
807
|
-
});
|
|
808
|
-
} else if (message.data?.answer) {
|
|
809
|
-
await this._resolveAnswers(message);
|
|
810
|
-
} else if (message.data?.signal) {
|
|
811
|
-
await this._handleSignal({
|
|
812
|
-
author,
|
|
813
|
-
recipient,
|
|
814
|
-
message
|
|
815
|
-
});
|
|
816
|
-
} else if (message.data?.signalBatch) {
|
|
817
|
-
await this._handleSignal({
|
|
818
|
-
author,
|
|
819
|
-
recipient,
|
|
820
|
-
message
|
|
821
|
-
});
|
|
822
|
-
} else {
|
|
823
|
-
import_log3.log.warn("unknown message", {
|
|
824
|
-
message
|
|
825
|
-
}, {
|
|
826
|
-
F: __dxlog_file3,
|
|
827
|
-
L: 82,
|
|
828
|
-
S: this,
|
|
829
|
-
C: (f, a) => f(...a)
|
|
830
|
-
});
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
async signal(message) {
|
|
834
|
-
(0, import_invariant2.invariant)(message.data?.signal || message.data?.signalBatch, "Invalid message", {
|
|
835
|
-
F: __dxlog_file3,
|
|
836
|
-
L: 87,
|
|
837
|
-
S: this,
|
|
838
|
-
A: [
|
|
839
|
-
"message.data?.signal || message.data?.signalBatch",
|
|
840
|
-
"'Invalid message'"
|
|
841
|
-
]
|
|
842
|
-
});
|
|
843
|
-
await this._sendReliableMessage({
|
|
844
|
-
author: message.author,
|
|
845
|
-
recipient: message.recipient,
|
|
846
|
-
message
|
|
847
|
-
});
|
|
848
|
-
}
|
|
849
|
-
async offer(message) {
|
|
850
|
-
const networkMessage = {
|
|
851
|
-
...message,
|
|
852
|
-
messageId: import_keys2.PublicKey.random()
|
|
853
|
-
};
|
|
854
|
-
return new Promise((resolve, reject) => {
|
|
855
|
-
this._offerRecords.set(networkMessage.messageId, {
|
|
856
|
-
resolve
|
|
857
|
-
});
|
|
858
|
-
this._sendReliableMessage({
|
|
859
|
-
author: message.author,
|
|
860
|
-
recipient: message.recipient,
|
|
861
|
-
message: networkMessage
|
|
862
|
-
}).catch((err) => reject(err));
|
|
863
|
-
});
|
|
864
|
-
}
|
|
865
|
-
async _sendReliableMessage({ author, recipient, message }) {
|
|
866
|
-
const networkMessage = {
|
|
867
|
-
...message,
|
|
868
|
-
// Setting unique message_id if it not specified yet.
|
|
869
|
-
messageId: message.messageId ?? import_keys2.PublicKey.random()
|
|
870
|
-
};
|
|
871
|
-
(0, import_log3.log)("sending", {
|
|
872
|
-
from: author,
|
|
873
|
-
to: recipient,
|
|
874
|
-
msg: networkMessage
|
|
875
|
-
}, {
|
|
876
|
-
F: __dxlog_file3,
|
|
877
|
-
L: 125,
|
|
878
|
-
S: this,
|
|
879
|
-
C: (f, a) => f(...a)
|
|
880
|
-
});
|
|
881
|
-
await this._sendMessage({
|
|
882
|
-
author,
|
|
883
|
-
recipient,
|
|
884
|
-
payload: {
|
|
885
|
-
type_url: "dxos.mesh.swarm.SwarmMessage",
|
|
886
|
-
value: SwarmMessage.encode(networkMessage)
|
|
887
|
-
}
|
|
888
|
-
});
|
|
889
|
-
}
|
|
890
|
-
async _resolveAnswers(message) {
|
|
891
|
-
(0, import_invariant2.invariant)(message.data?.answer?.offerMessageId, "No offerMessageId", {
|
|
892
|
-
F: __dxlog_file3,
|
|
893
|
-
L: 137,
|
|
894
|
-
S: this,
|
|
895
|
-
A: [
|
|
896
|
-
"message.data?.answer?.offerMessageId",
|
|
897
|
-
"'No offerMessageId'"
|
|
898
|
-
]
|
|
899
|
-
});
|
|
900
|
-
const offerRecord = this._offerRecords.get(message.data.answer.offerMessageId);
|
|
901
|
-
if (offerRecord) {
|
|
902
|
-
this._offerRecords.delete(message.data.answer.offerMessageId);
|
|
903
|
-
(0, import_invariant2.invariant)(message.data?.answer, "No answer", {
|
|
904
|
-
F: __dxlog_file3,
|
|
905
|
-
L: 141,
|
|
906
|
-
S: this,
|
|
907
|
-
A: [
|
|
908
|
-
"message.data?.answer",
|
|
909
|
-
"'No answer'"
|
|
910
|
-
]
|
|
911
|
-
});
|
|
912
|
-
(0, import_log3.log)("resolving", {
|
|
913
|
-
answer: message.data.answer
|
|
914
|
-
}, {
|
|
915
|
-
F: __dxlog_file3,
|
|
916
|
-
L: 142,
|
|
917
|
-
S: this,
|
|
918
|
-
C: (f, a) => f(...a)
|
|
919
|
-
});
|
|
920
|
-
offerRecord.resolve(message.data.answer);
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
async _handleOffer({ author, recipient, message }) {
|
|
924
|
-
(0, import_invariant2.invariant)(message.data.offer, "No offer", {
|
|
925
|
-
F: __dxlog_file3,
|
|
926
|
-
L: 156,
|
|
927
|
-
S: this,
|
|
928
|
-
A: [
|
|
929
|
-
"message.data.offer",
|
|
930
|
-
"'No offer'"
|
|
931
|
-
]
|
|
932
|
-
});
|
|
933
|
-
const offerMessage = {
|
|
934
|
-
author,
|
|
935
|
-
recipient,
|
|
936
|
-
...message,
|
|
937
|
-
data: {
|
|
938
|
-
offer: message.data.offer
|
|
939
|
-
}
|
|
940
|
-
};
|
|
941
|
-
const answer = await this._onOffer(offerMessage);
|
|
942
|
-
answer.offerMessageId = message.messageId;
|
|
943
|
-
try {
|
|
944
|
-
await this._sendReliableMessage({
|
|
945
|
-
author: recipient,
|
|
946
|
-
recipient: author,
|
|
947
|
-
message: {
|
|
948
|
-
topic: message.topic,
|
|
949
|
-
sessionId: message.sessionId,
|
|
950
|
-
data: {
|
|
951
|
-
answer
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
});
|
|
955
|
-
} catch (err) {
|
|
956
|
-
if (err instanceof import_protocols2.TimeoutError) {
|
|
957
|
-
import_log3.log.info("timeout sending answer to offer", {
|
|
958
|
-
err
|
|
959
|
-
}, {
|
|
960
|
-
F: __dxlog_file3,
|
|
961
|
-
L: 177,
|
|
962
|
-
S: this,
|
|
963
|
-
C: (f, a) => f(...a)
|
|
964
|
-
});
|
|
965
|
-
} else {
|
|
966
|
-
import_log3.log.info("error sending answer to offer", {
|
|
967
|
-
err
|
|
968
|
-
}, {
|
|
969
|
-
F: __dxlog_file3,
|
|
970
|
-
L: 179,
|
|
971
|
-
S: this,
|
|
972
|
-
C: (f, a) => f(...a)
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
async _handleSignal({ author, recipient, message }) {
|
|
978
|
-
(0, import_invariant2.invariant)(message.messageId, void 0, {
|
|
979
|
-
F: __dxlog_file3,
|
|
980
|
-
L: 193,
|
|
981
|
-
S: this,
|
|
982
|
-
A: [
|
|
983
|
-
"message.messageId",
|
|
984
|
-
""
|
|
985
|
-
]
|
|
986
|
-
});
|
|
987
|
-
(0, import_invariant2.invariant)(message.data.signal || message.data.signalBatch, "Invalid message", {
|
|
988
|
-
F: __dxlog_file3,
|
|
989
|
-
L: 194,
|
|
990
|
-
S: this,
|
|
991
|
-
A: [
|
|
992
|
-
"message.data.signal || message.data.signalBatch",
|
|
993
|
-
"'Invalid message'"
|
|
994
|
-
]
|
|
995
|
-
});
|
|
996
|
-
const signalMessage = {
|
|
997
|
-
author,
|
|
998
|
-
recipient,
|
|
999
|
-
...message,
|
|
1000
|
-
data: {
|
|
1001
|
-
signal: message.data.signal,
|
|
1002
|
-
signalBatch: message.data.signalBatch
|
|
1003
|
-
}
|
|
1004
|
-
};
|
|
1005
|
-
await this._onSignal(signalMessage);
|
|
1006
|
-
}
|
|
1007
|
-
};
|
|
1008
|
-
function _ts_decorate2(decorators, target, key, desc) {
|
|
1009
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1010
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1011
|
-
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;
|
|
1012
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1013
|
-
}
|
|
1014
|
-
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/swarm/peer.ts";
|
|
1015
|
-
var ConnectionDisplacedError = class extends import_protocols4.SystemError {
|
|
1016
|
-
constructor() {
|
|
1017
|
-
super("Connection displaced by remote initiator.");
|
|
1018
|
-
}
|
|
1019
|
-
};
|
|
1020
|
-
var CONNECTION_COUNTS_STABLE_AFTER = 5e3;
|
|
1021
|
-
var Peer = class {
|
|
1022
|
-
constructor(remoteInfo, topic, localInfo, _signalMessaging, _protocolProvider, _transportFactory, _connectionLimiter, _callbacks) {
|
|
1023
|
-
this.remoteInfo = remoteInfo;
|
|
1024
|
-
this.topic = topic;
|
|
1025
|
-
this.localInfo = localInfo;
|
|
1026
|
-
this._signalMessaging = _signalMessaging;
|
|
1027
|
-
this._protocolProvider = _protocolProvider;
|
|
1028
|
-
this._transportFactory = _transportFactory;
|
|
1029
|
-
this._connectionLimiter = _connectionLimiter;
|
|
1030
|
-
this._callbacks = _callbacks;
|
|
1031
|
-
this._availableAfter = 0;
|
|
1032
|
-
this.availableToConnect = true;
|
|
1033
|
-
this._ctx = new import_context4.Context(void 0, {
|
|
1034
|
-
F: __dxlog_file4,
|
|
1035
|
-
L: 80
|
|
1036
|
-
});
|
|
1037
|
-
this.advertizing = false;
|
|
1038
|
-
this.initiating = false;
|
|
1039
|
-
this.connectionDisplaced = new import_async4.Event();
|
|
1040
|
-
}
|
|
1041
|
-
/**
|
|
1042
|
-
* Respond to remote offer.
|
|
1043
|
-
*/
|
|
1044
|
-
async onOffer(message) {
|
|
1045
|
-
const remote = message.author;
|
|
1046
|
-
if (this.connection && ![
|
|
1047
|
-
ConnectionState.CREATED,
|
|
1048
|
-
ConnectionState.INITIAL,
|
|
1049
|
-
ConnectionState.CONNECTING
|
|
1050
|
-
].includes(this.connection.state)) {
|
|
1051
|
-
import_log5.log.info(`received offer when connection already in ${this.connection.state} state`, void 0, {
|
|
1052
|
-
F: __dxlog_file4,
|
|
1053
|
-
L: 115,
|
|
1054
|
-
S: this,
|
|
1055
|
-
C: (f, a) => f(...a)
|
|
1056
|
-
});
|
|
1057
|
-
return {
|
|
1058
|
-
accept: false
|
|
1059
|
-
};
|
|
1060
|
-
}
|
|
1061
|
-
if (this.connection || this.initiating) {
|
|
1062
|
-
if (remote.peerKey < this.localInfo.peerKey) {
|
|
1063
|
-
(0, import_log5.log)("close local connection", {
|
|
1064
|
-
localPeer: this.localInfo,
|
|
1065
|
-
topic: this.topic,
|
|
1066
|
-
remotePeer: this.remoteInfo,
|
|
1067
|
-
sessionId: this.connection?.sessionId
|
|
1068
|
-
}, {
|
|
1069
|
-
F: __dxlog_file4,
|
|
1070
|
-
L: 124,
|
|
1071
|
-
S: this,
|
|
1072
|
-
C: (f, a) => f(...a)
|
|
1073
|
-
});
|
|
1074
|
-
if (this.connection) {
|
|
1075
|
-
await this.closeConnection(new ConnectionDisplacedError());
|
|
1076
|
-
}
|
|
1077
|
-
} else {
|
|
1078
|
-
return {
|
|
1079
|
-
accept: false
|
|
1080
|
-
};
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
if (await this._callbacks.onOffer(remote)) {
|
|
1084
|
-
if (!this.connection) {
|
|
1085
|
-
(0, import_invariant4.invariant)(message.sessionId, void 0, {
|
|
1086
|
-
F: __dxlog_file4,
|
|
1087
|
-
L: 144,
|
|
1088
|
-
S: this,
|
|
1089
|
-
A: [
|
|
1090
|
-
"message.sessionId",
|
|
1091
|
-
""
|
|
1092
|
-
]
|
|
1093
|
-
});
|
|
1094
|
-
const connection = this._createConnection(false, message.sessionId);
|
|
1095
|
-
try {
|
|
1096
|
-
await this._connectionLimiter.connecting(message.sessionId);
|
|
1097
|
-
connection.initiate();
|
|
1098
|
-
await connection.openConnection();
|
|
1099
|
-
} catch (err) {
|
|
1100
|
-
if (!(err instanceof import_protocols4.CancelledError)) {
|
|
1101
|
-
import_log5.log.info("connection error", {
|
|
1102
|
-
topic: this.topic,
|
|
1103
|
-
peerId: this.localInfo,
|
|
1104
|
-
remoteId: this.remoteInfo,
|
|
1105
|
-
err
|
|
1106
|
-
}, {
|
|
1107
|
-
F: __dxlog_file4,
|
|
1108
|
-
L: 154,
|
|
1109
|
-
S: this,
|
|
1110
|
-
C: (f, a) => f(...a)
|
|
1111
|
-
});
|
|
1112
|
-
}
|
|
1113
|
-
await this.closeConnection(err);
|
|
1114
|
-
}
|
|
1115
|
-
return {
|
|
1116
|
-
accept: true
|
|
1117
|
-
};
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
return {
|
|
1121
|
-
accept: false
|
|
1122
|
-
};
|
|
1123
|
-
}
|
|
1124
|
-
/**
|
|
1125
|
-
* Initiate a connection to the remote peer.
|
|
1126
|
-
*/
|
|
1127
|
-
async initiateConnection() {
|
|
1128
|
-
(0, import_invariant4.invariant)(!this.initiating, "Initiation in progress.", {
|
|
1129
|
-
F: __dxlog_file4,
|
|
1130
|
-
L: 171,
|
|
1131
|
-
S: this,
|
|
1132
|
-
A: [
|
|
1133
|
-
"!this.initiating",
|
|
1134
|
-
"'Initiation in progress.'"
|
|
1135
|
-
]
|
|
1136
|
-
});
|
|
1137
|
-
(0, import_invariant4.invariant)(!this.connection, "Already connected.", {
|
|
1138
|
-
F: __dxlog_file4,
|
|
1139
|
-
L: 172,
|
|
1140
|
-
S: this,
|
|
1141
|
-
A: [
|
|
1142
|
-
"!this.connection",
|
|
1143
|
-
"'Already connected.'"
|
|
1144
|
-
]
|
|
1145
|
-
});
|
|
1146
|
-
const sessionId = import_keys4.PublicKey.random();
|
|
1147
|
-
(0, import_log5.log)("initiating...", {
|
|
1148
|
-
local: this.localInfo,
|
|
1149
|
-
topic: this.topic,
|
|
1150
|
-
remote: this.remoteInfo,
|
|
1151
|
-
sessionId
|
|
1152
|
-
}, {
|
|
1153
|
-
F: __dxlog_file4,
|
|
1154
|
-
L: 174,
|
|
1155
|
-
S: this,
|
|
1156
|
-
C: (f, a) => f(...a)
|
|
1157
|
-
});
|
|
1158
|
-
const connection = this._createConnection(true, sessionId);
|
|
1159
|
-
this.initiating = true;
|
|
1160
|
-
let answer;
|
|
1161
|
-
try {
|
|
1162
|
-
await this._connectionLimiter.connecting(sessionId);
|
|
1163
|
-
connection.initiate();
|
|
1164
|
-
answer = await this._signalMessaging.offer({
|
|
1165
|
-
author: this.localInfo,
|
|
1166
|
-
recipient: this.remoteInfo,
|
|
1167
|
-
sessionId,
|
|
1168
|
-
topic: this.topic,
|
|
1169
|
-
data: {
|
|
1170
|
-
offer: {}
|
|
1171
|
-
}
|
|
1172
|
-
});
|
|
1173
|
-
(0, import_log5.log)("received", {
|
|
1174
|
-
answer,
|
|
1175
|
-
topic: this.topic,
|
|
1176
|
-
local: this.localInfo,
|
|
1177
|
-
remote: this.remoteInfo
|
|
1178
|
-
}, {
|
|
1179
|
-
F: __dxlog_file4,
|
|
1180
|
-
L: 191,
|
|
1181
|
-
S: this,
|
|
1182
|
-
C: (f, a) => f(...a)
|
|
1183
|
-
});
|
|
1184
|
-
if (connection.state !== ConnectionState.INITIAL) {
|
|
1185
|
-
(0, import_log5.log)("ignoring response", void 0, {
|
|
1186
|
-
F: __dxlog_file4,
|
|
1187
|
-
L: 193,
|
|
1188
|
-
S: this,
|
|
1189
|
-
C: (f, a) => f(...a)
|
|
1190
|
-
});
|
|
1191
|
-
return;
|
|
1192
|
-
}
|
|
1193
|
-
} catch (err) {
|
|
1194
|
-
(0, import_log5.log)("initiation error: send offer", {
|
|
1195
|
-
err,
|
|
1196
|
-
topic: this.topic,
|
|
1197
|
-
local: this.localInfo,
|
|
1198
|
-
remote: this.remoteInfo
|
|
1199
|
-
}, {
|
|
1200
|
-
F: __dxlog_file4,
|
|
1201
|
-
L: 197,
|
|
1202
|
-
S: this,
|
|
1203
|
-
C: (f, a) => f(...a)
|
|
1204
|
-
});
|
|
1205
|
-
await connection.abort(err);
|
|
1206
|
-
throw err;
|
|
1207
|
-
} finally {
|
|
1208
|
-
this.initiating = false;
|
|
1209
|
-
}
|
|
1210
|
-
try {
|
|
1211
|
-
if (!answer.accept) {
|
|
1212
|
-
this._callbacks.onRejected();
|
|
1213
|
-
return;
|
|
1214
|
-
}
|
|
1215
|
-
} catch (err) {
|
|
1216
|
-
(0, import_log5.log)("initiation error: accept answer", {
|
|
1217
|
-
err,
|
|
1218
|
-
topic: this.topic,
|
|
1219
|
-
local: this.localInfo,
|
|
1220
|
-
remote: this.remoteInfo
|
|
1221
|
-
}, {
|
|
1222
|
-
F: __dxlog_file4,
|
|
1223
|
-
L: 210,
|
|
1224
|
-
S: this,
|
|
1225
|
-
C: (f, a) => f(...a)
|
|
1226
|
-
});
|
|
1227
|
-
await connection.abort(err);
|
|
1228
|
-
throw err;
|
|
1229
|
-
} finally {
|
|
1230
|
-
this.initiating = false;
|
|
1231
|
-
}
|
|
1232
|
-
try {
|
|
1233
|
-
(0, import_log5.log)("opening connection as initiator", void 0, {
|
|
1234
|
-
F: __dxlog_file4,
|
|
1235
|
-
L: 223,
|
|
1236
|
-
S: this,
|
|
1237
|
-
C: (f, a) => f(...a)
|
|
1238
|
-
});
|
|
1239
|
-
await connection.openConnection();
|
|
1240
|
-
this._callbacks.onAccepted();
|
|
1241
|
-
} catch (err) {
|
|
1242
|
-
(0, import_log5.log)("initiation error: open connection", {
|
|
1243
|
-
err,
|
|
1244
|
-
topic: this.topic,
|
|
1245
|
-
local: this.localInfo,
|
|
1246
|
-
remote: this.remoteInfo
|
|
1247
|
-
}, {
|
|
1248
|
-
F: __dxlog_file4,
|
|
1249
|
-
L: 227,
|
|
1250
|
-
S: this,
|
|
1251
|
-
C: (f, a) => f(...a)
|
|
1252
|
-
});
|
|
1253
|
-
import_log5.log.warn("closing connection due to unhandled error on openConnection", {
|
|
1254
|
-
err
|
|
1255
|
-
}, {
|
|
1256
|
-
F: __dxlog_file4,
|
|
1257
|
-
L: 234,
|
|
1258
|
-
S: this,
|
|
1259
|
-
C: (f, a) => f(...a)
|
|
1260
|
-
});
|
|
1261
|
-
await this.closeConnection(err);
|
|
1262
|
-
throw err;
|
|
1263
|
-
} finally {
|
|
1264
|
-
this.initiating = false;
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
/**
|
|
1268
|
-
* Create new connection.
|
|
1269
|
-
* Either we're initiating a connection or creating one in response to an offer from the other peer.
|
|
1270
|
-
*/
|
|
1271
|
-
_createConnection(initiator, sessionId) {
|
|
1272
|
-
(0, import_log5.log)("creating connection", {
|
|
1273
|
-
topic: this.topic,
|
|
1274
|
-
peerId: this.localInfo,
|
|
1275
|
-
remoteId: this.remoteInfo,
|
|
1276
|
-
initiator,
|
|
1277
|
-
sessionId
|
|
1278
|
-
}, {
|
|
1279
|
-
F: __dxlog_file4,
|
|
1280
|
-
L: 248,
|
|
1281
|
-
S: this,
|
|
1282
|
-
C: (f, a) => f(...a)
|
|
1283
|
-
});
|
|
1284
|
-
(0, import_invariant4.invariant)(!this.connection, "Already connected.", {
|
|
1285
|
-
F: __dxlog_file4,
|
|
1286
|
-
L: 255,
|
|
1287
|
-
S: this,
|
|
1288
|
-
A: [
|
|
1289
|
-
"!this.connection",
|
|
1290
|
-
"'Already connected.'"
|
|
1291
|
-
]
|
|
1292
|
-
});
|
|
1293
|
-
const connection = new Connection(
|
|
1294
|
-
this.topic,
|
|
1295
|
-
this.localInfo,
|
|
1296
|
-
this.remoteInfo,
|
|
1297
|
-
sessionId,
|
|
1298
|
-
initiator,
|
|
1299
|
-
this._signalMessaging,
|
|
1300
|
-
// TODO(dmaretskyi): Init only when connection is established.
|
|
1301
|
-
this._protocolProvider({
|
|
1302
|
-
initiator,
|
|
1303
|
-
localPeerId: import_keys4.PublicKey.from(this.localInfo.peerKey),
|
|
1304
|
-
remotePeerId: import_keys4.PublicKey.from(this.remoteInfo.peerKey),
|
|
1305
|
-
topic: this.topic
|
|
1306
|
-
}),
|
|
1307
|
-
this._transportFactory,
|
|
1308
|
-
{
|
|
1309
|
-
onConnected: () => {
|
|
1310
|
-
this.availableToConnect = true;
|
|
1311
|
-
this._lastConnectionTime = Date.now();
|
|
1312
|
-
this._callbacks.onConnected();
|
|
1313
|
-
this._connectionLimiter.doneConnecting(sessionId);
|
|
1314
|
-
import_log5.log.trace("dxos.mesh.connection.connected", {
|
|
1315
|
-
topic: this.topic,
|
|
1316
|
-
localPeerId: this.localInfo,
|
|
1317
|
-
remotePeerId: this.remoteInfo,
|
|
1318
|
-
sessionId,
|
|
1319
|
-
initiator
|
|
1320
|
-
}, {
|
|
1321
|
-
F: __dxlog_file4,
|
|
1322
|
-
L: 279,
|
|
1323
|
-
S: this,
|
|
1324
|
-
C: (f, a) => f(...a)
|
|
1325
|
-
});
|
|
1326
|
-
},
|
|
1327
|
-
onClosed: (err) => {
|
|
1328
|
-
const logMeta = {
|
|
1329
|
-
topic: this.topic,
|
|
1330
|
-
peerId: this.localInfo,
|
|
1331
|
-
remoteId: this.remoteInfo,
|
|
1332
|
-
initiator
|
|
1333
|
-
};
|
|
1334
|
-
(0, import_log5.log)("connection closed", logMeta, {
|
|
1335
|
-
F: __dxlog_file4,
|
|
1336
|
-
L: 289,
|
|
1337
|
-
S: this,
|
|
1338
|
-
C: (f, a) => f(...a)
|
|
1339
|
-
});
|
|
1340
|
-
this._connectionLimiter.doneConnecting(sessionId);
|
|
1341
|
-
(0, import_invariant4.invariant)(this.connection === connection, "Connection mismatch (race condition).", {
|
|
1342
|
-
F: __dxlog_file4,
|
|
1343
|
-
L: 294,
|
|
1344
|
-
S: this,
|
|
1345
|
-
A: [
|
|
1346
|
-
"this.connection === connection",
|
|
1347
|
-
"'Connection mismatch (race condition).'"
|
|
1348
|
-
]
|
|
1349
|
-
});
|
|
1350
|
-
import_log5.log.trace("dxos.mesh.connection.closed", {
|
|
1351
|
-
topic: this.topic,
|
|
1352
|
-
localPeerId: this.localInfo,
|
|
1353
|
-
remotePeerId: this.remoteInfo,
|
|
1354
|
-
sessionId,
|
|
1355
|
-
initiator
|
|
1356
|
-
}, {
|
|
1357
|
-
F: __dxlog_file4,
|
|
1358
|
-
L: 296,
|
|
1359
|
-
S: this,
|
|
1360
|
-
C: (f, a) => f(...a)
|
|
1361
|
-
});
|
|
1362
|
-
if (err instanceof ConnectionDisplacedError) {
|
|
1363
|
-
this.connectionDisplaced.emit(this.connection);
|
|
1364
|
-
} else {
|
|
1365
|
-
if (this._lastConnectionTime && this._lastConnectionTime + CONNECTION_COUNTS_STABLE_AFTER < Date.now()) {
|
|
1366
|
-
this._availableAfter = 0;
|
|
1367
|
-
} else {
|
|
1368
|
-
this.availableToConnect = false;
|
|
1369
|
-
this._availableAfter = increaseInterval(this._availableAfter);
|
|
1370
|
-
}
|
|
1371
|
-
this._callbacks.onDisconnected();
|
|
1372
|
-
(0, import_async4.scheduleTask)(this._connectionCtx, () => {
|
|
1373
|
-
(0, import_log5.log)("peer became available", logMeta, {
|
|
1374
|
-
F: __dxlog_file4,
|
|
1375
|
-
L: 320,
|
|
1376
|
-
S: this,
|
|
1377
|
-
C: (f, a) => f(...a)
|
|
1378
|
-
});
|
|
1379
|
-
this.availableToConnect = true;
|
|
1380
|
-
this._callbacks.onPeerAvailable();
|
|
1381
|
-
}, this._availableAfter);
|
|
1382
|
-
}
|
|
1383
|
-
this.connection = void 0;
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1386
|
-
);
|
|
1387
|
-
this._callbacks.onInitiated(connection);
|
|
1388
|
-
void this._connectionCtx?.dispose();
|
|
1389
|
-
this._connectionCtx = this._ctx.derive();
|
|
1390
|
-
connection.errors.handle((err) => {
|
|
1391
|
-
import_log5.log.info("connection error, closing", {
|
|
1392
|
-
topic: this.topic,
|
|
1393
|
-
peerId: this.localInfo,
|
|
1394
|
-
remoteId: this.remoteInfo,
|
|
1395
|
-
initiator,
|
|
1396
|
-
err
|
|
1397
|
-
}, {
|
|
1398
|
-
F: __dxlog_file4,
|
|
1399
|
-
L: 338,
|
|
1400
|
-
S: this,
|
|
1401
|
-
C: (f, a) => f(...a)
|
|
1402
|
-
});
|
|
1403
|
-
import_log5.log.trace("dxos.mesh.connection.error", {
|
|
1404
|
-
topic: this.topic,
|
|
1405
|
-
localPeerId: this.localInfo,
|
|
1406
|
-
remotePeerId: this.remoteInfo,
|
|
1407
|
-
sessionId,
|
|
1408
|
-
initiator,
|
|
1409
|
-
err
|
|
1410
|
-
}, {
|
|
1411
|
-
F: __dxlog_file4,
|
|
1412
|
-
L: 345,
|
|
1413
|
-
S: this,
|
|
1414
|
-
C: (f, a) => f(...a)
|
|
1415
|
-
});
|
|
1416
|
-
void this.closeConnection(err);
|
|
1417
|
-
});
|
|
1418
|
-
this.connection = connection;
|
|
1419
|
-
return connection;
|
|
1420
|
-
}
|
|
1421
|
-
async closeConnection(err) {
|
|
1422
|
-
if (!this.connection) {
|
|
1423
|
-
return;
|
|
1424
|
-
}
|
|
1425
|
-
const connection = this.connection;
|
|
1426
|
-
(0, import_log5.log)("closing...", {
|
|
1427
|
-
peerId: this.remoteInfo,
|
|
1428
|
-
sessionId: connection.sessionId
|
|
1429
|
-
}, {
|
|
1430
|
-
F: __dxlog_file4,
|
|
1431
|
-
L: 370,
|
|
1432
|
-
S: this,
|
|
1433
|
-
C: (f, a) => f(...a)
|
|
1434
|
-
});
|
|
1435
|
-
await connection.close({
|
|
1436
|
-
error: err
|
|
1437
|
-
});
|
|
1438
|
-
(0, import_log5.log)("closed", {
|
|
1439
|
-
peerId: this.remoteInfo,
|
|
1440
|
-
sessionId: connection.sessionId
|
|
1441
|
-
}, {
|
|
1442
|
-
F: __dxlog_file4,
|
|
1443
|
-
L: 376,
|
|
1444
|
-
S: this,
|
|
1445
|
-
C: (f, a) => f(...a)
|
|
1446
|
-
});
|
|
1447
|
-
}
|
|
1448
|
-
async onSignal(message) {
|
|
1449
|
-
if (!this.connection) {
|
|
1450
|
-
(0, import_log5.log)("dropping signal message for non-existent connection", {
|
|
1451
|
-
message
|
|
1452
|
-
}, {
|
|
1453
|
-
F: __dxlog_file4,
|
|
1454
|
-
L: 381,
|
|
1455
|
-
S: this,
|
|
1456
|
-
C: (f, a) => f(...a)
|
|
1457
|
-
});
|
|
1458
|
-
return;
|
|
1459
|
-
}
|
|
1460
|
-
await this.connection.signal(message);
|
|
1461
|
-
}
|
|
1462
|
-
async safeDestroy(reason) {
|
|
1463
|
-
await this._ctx.dispose();
|
|
1464
|
-
(0, import_log5.log)("Destroying peer", {
|
|
1465
|
-
peerId: this.remoteInfo,
|
|
1466
|
-
topic: this.topic
|
|
1467
|
-
}, {
|
|
1468
|
-
F: __dxlog_file4,
|
|
1469
|
-
L: 391,
|
|
1470
|
-
S: this,
|
|
1471
|
-
C: (f, a) => f(...a)
|
|
1472
|
-
});
|
|
1473
|
-
await this?.connection?.close({
|
|
1474
|
-
reason
|
|
1475
|
-
});
|
|
1476
|
-
}
|
|
1477
|
-
};
|
|
1478
|
-
_ts_decorate2([
|
|
1479
|
-
import_async4.synchronized
|
|
1480
|
-
], Peer.prototype, "safeDestroy", null);
|
|
1481
|
-
var increaseInterval = (interval) => {
|
|
1482
|
-
if (interval === 0) {
|
|
1483
|
-
return 50;
|
|
1484
|
-
} else if (interval < 500) {
|
|
1485
|
-
return 500;
|
|
1486
|
-
} else if (interval < 1e3) {
|
|
1487
|
-
return 1e3;
|
|
1488
|
-
} else if (interval < 5e3) {
|
|
1489
|
-
return 5e3;
|
|
1490
|
-
}
|
|
1491
|
-
return 1e4;
|
|
1492
|
-
};
|
|
1493
|
-
function _ts_decorate3(decorators, target, key, desc) {
|
|
1494
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1495
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1496
|
-
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;
|
|
1497
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1498
|
-
}
|
|
1499
|
-
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/swarm/swarm.ts";
|
|
1500
|
-
var INITIATION_DELAY = 100;
|
|
1501
|
-
var getClassName = (obj) => Object.getPrototypeOf(obj).constructor.name;
|
|
1502
|
-
var Swarm = class {
|
|
1503
|
-
// TODO(burdon): Swarm => Peer.create/destroy =< Connection.open/close
|
|
1504
|
-
// TODO(burdon): Pass in object.
|
|
1505
|
-
constructor(_topic, _ownPeer, _topology, _protocolProvider, _messenger, _transportFactory, _label, _connectionLimiter, _initiationDelay = INITIATION_DELAY) {
|
|
1506
|
-
this._topic = _topic;
|
|
1507
|
-
this._ownPeer = _ownPeer;
|
|
1508
|
-
this._topology = _topology;
|
|
1509
|
-
this._protocolProvider = _protocolProvider;
|
|
1510
|
-
this._messenger = _messenger;
|
|
1511
|
-
this._transportFactory = _transportFactory;
|
|
1512
|
-
this._label = _label;
|
|
1513
|
-
this._connectionLimiter = _connectionLimiter;
|
|
1514
|
-
this._initiationDelay = _initiationDelay;
|
|
1515
|
-
this._ctx = new import_context3.Context(void 0, {
|
|
1516
|
-
F: __dxlog_file5,
|
|
1517
|
-
L: 38
|
|
1518
|
-
});
|
|
1519
|
-
this._listeningHandle = void 0;
|
|
1520
|
-
this._peers = new import_util3.ComplexMap(import_messaging.PeerInfoHash);
|
|
1521
|
-
this._instanceId = import_keys3.PublicKey.random().toHex();
|
|
1522
|
-
this.connectionAdded = new import_async3.Event();
|
|
1523
|
-
this.disconnected = new import_async3.Event();
|
|
1524
|
-
this.connected = new import_async3.Event();
|
|
1525
|
-
this.errors = new import_debug2.ErrorStream();
|
|
1526
|
-
import_log4.log.trace("dxos.mesh.swarm.constructor", import_protocols3.trace.begin({
|
|
1527
|
-
id: this._instanceId,
|
|
1528
|
-
data: {
|
|
1529
|
-
topic: this._topic.toHex(),
|
|
1530
|
-
peer: this._ownPeer
|
|
1531
|
-
}
|
|
1532
|
-
}), {
|
|
1533
|
-
F: __dxlog_file5,
|
|
1534
|
-
L: 88,
|
|
1535
|
-
S: this,
|
|
1536
|
-
C: (f, a) => f(...a)
|
|
1537
|
-
});
|
|
1538
|
-
(0, import_log4.log)("creating swarm", {
|
|
1539
|
-
peerId: _ownPeer
|
|
1540
|
-
}, {
|
|
1541
|
-
F: __dxlog_file5,
|
|
1542
|
-
L: 92,
|
|
1543
|
-
S: this,
|
|
1544
|
-
C: (f, a) => f(...a)
|
|
1545
|
-
});
|
|
1546
|
-
_topology.init(this._getSwarmController());
|
|
1547
|
-
this._swarmMessenger = new SwarmMessenger({
|
|
1548
|
-
sendMessage: async (msg) => await this._messenger.sendMessage(msg),
|
|
1549
|
-
onSignal: async (msg) => await this.onSignal(msg),
|
|
1550
|
-
onOffer: async (msg) => await this.onOffer(msg),
|
|
1551
|
-
topic: this._topic
|
|
1552
|
-
});
|
|
1553
|
-
import_log4.log.trace("dxos.mesh.swarm.constructor", import_protocols3.trace.end({
|
|
1554
|
-
id: this._instanceId
|
|
1555
|
-
}), {
|
|
1556
|
-
F: __dxlog_file5,
|
|
1557
|
-
L: 101,
|
|
1558
|
-
S: this,
|
|
1559
|
-
C: (f, a) => f(...a)
|
|
1560
|
-
});
|
|
1561
|
-
}
|
|
1562
|
-
get connections() {
|
|
1563
|
-
return Array.from(this._peers.values()).map((peer) => peer.connection).filter(import_util3.isNonNullable);
|
|
1564
|
-
}
|
|
1565
|
-
get ownPeerId() {
|
|
1566
|
-
return import_keys3.PublicKey.from(this._ownPeer.peerKey);
|
|
1567
|
-
}
|
|
1568
|
-
get ownPeer() {
|
|
1569
|
-
return this._ownPeer;
|
|
1570
|
-
}
|
|
1571
|
-
/**
|
|
1572
|
-
* Custom label assigned to this swarm. Used in devtools to display human-readable names for swarms.
|
|
1573
|
-
*/
|
|
1574
|
-
get label() {
|
|
1575
|
-
return this._label;
|
|
1576
|
-
}
|
|
1577
|
-
get topic() {
|
|
1578
|
-
return this._topic;
|
|
1579
|
-
}
|
|
1580
|
-
async open() {
|
|
1581
|
-
(0, import_invariant3.invariant)(!this._listeningHandle, void 0, {
|
|
1582
|
-
F: __dxlog_file5,
|
|
1583
|
-
L: 132,
|
|
1584
|
-
S: this,
|
|
1585
|
-
A: [
|
|
1586
|
-
"!this._listeningHandle",
|
|
1587
|
-
""
|
|
1588
|
-
]
|
|
1589
|
-
});
|
|
1590
|
-
this._listeningHandle = await this._messenger.listen({
|
|
1591
|
-
peer: this._ownPeer,
|
|
1592
|
-
payloadType: "dxos.mesh.swarm.SwarmMessage",
|
|
1593
|
-
onMessage: async (message) => {
|
|
1594
|
-
await this._swarmMessenger.receiveMessage(message).catch((err) => import_log4.log.info("Error while receiving message", {
|
|
1595
|
-
err
|
|
1596
|
-
}, {
|
|
1597
|
-
F: __dxlog_file5,
|
|
1598
|
-
L: 140,
|
|
1599
|
-
S: this,
|
|
1600
|
-
C: (f, a) => f(...a)
|
|
1601
|
-
}));
|
|
1602
|
-
}
|
|
1603
|
-
});
|
|
1604
|
-
}
|
|
1605
|
-
async destroy() {
|
|
1606
|
-
(0, import_log4.log)("destroying...", void 0, {
|
|
1607
|
-
F: __dxlog_file5,
|
|
1608
|
-
L: 146,
|
|
1609
|
-
S: this,
|
|
1610
|
-
C: (f, a) => f(...a)
|
|
1611
|
-
});
|
|
1612
|
-
await this._listeningHandle?.unsubscribe();
|
|
1613
|
-
this._listeningHandle = void 0;
|
|
1614
|
-
await this._ctx.dispose();
|
|
1615
|
-
await this._topology.destroy();
|
|
1616
|
-
await Promise.all(Array.from(this._peers.keys()).map((key) => this._destroyPeer(key, "swarm destroyed")));
|
|
1617
|
-
(0, import_log4.log)("destroyed", void 0, {
|
|
1618
|
-
F: __dxlog_file5,
|
|
1619
|
-
L: 153,
|
|
1620
|
-
S: this,
|
|
1621
|
-
C: (f, a) => f(...a)
|
|
1622
|
-
});
|
|
1623
|
-
}
|
|
1624
|
-
async setTopology(topology) {
|
|
1625
|
-
(0, import_invariant3.invariant)(!this._ctx.disposed, "Swarm is offline", {
|
|
1626
|
-
F: __dxlog_file5,
|
|
1627
|
-
L: 157,
|
|
1628
|
-
S: this,
|
|
1629
|
-
A: [
|
|
1630
|
-
"!this._ctx.disposed",
|
|
1631
|
-
"'Swarm is offline'"
|
|
1632
|
-
]
|
|
1633
|
-
});
|
|
1634
|
-
if (topology === this._topology) {
|
|
1635
|
-
return;
|
|
1636
|
-
}
|
|
1637
|
-
(0, import_log4.log)("setting topology", {
|
|
1638
|
-
previous: getClassName(this._topology),
|
|
1639
|
-
topology: getClassName(topology)
|
|
1640
|
-
}, {
|
|
1641
|
-
F: __dxlog_file5,
|
|
1642
|
-
L: 161,
|
|
1643
|
-
S: this,
|
|
1644
|
-
C: (f, a) => f(...a)
|
|
1645
|
-
});
|
|
1646
|
-
await this._topology.destroy();
|
|
1647
|
-
this._topology = topology;
|
|
1648
|
-
this._topology.init(this._getSwarmController());
|
|
1649
|
-
this._topology.update();
|
|
1650
|
-
}
|
|
1651
|
-
async onSwarmEvent(swarmEvent) {
|
|
1652
|
-
(0, import_log4.log)("swarm event", {
|
|
1653
|
-
swarmEvent
|
|
1654
|
-
}, {
|
|
1655
|
-
F: __dxlog_file5,
|
|
1656
|
-
L: 174,
|
|
1657
|
-
S: this,
|
|
1658
|
-
C: (f, a) => f(...a)
|
|
1659
|
-
});
|
|
1660
|
-
if (this._ctx.disposed) {
|
|
1661
|
-
(0, import_log4.log)("swarm event ignored for disposed swarm", void 0, {
|
|
1662
|
-
F: __dxlog_file5,
|
|
1663
|
-
L: 177,
|
|
1664
|
-
S: this,
|
|
1665
|
-
C: (f, a) => f(...a)
|
|
1666
|
-
});
|
|
1667
|
-
return;
|
|
1668
|
-
}
|
|
1669
|
-
if (swarmEvent.peerAvailable) {
|
|
1670
|
-
const peerId = swarmEvent.peerAvailable.peer.peerKey;
|
|
1671
|
-
if (peerId !== this._ownPeer.peerKey) {
|
|
1672
|
-
(0, import_log4.log)("new peer", {
|
|
1673
|
-
peerId
|
|
1674
|
-
}, {
|
|
1675
|
-
F: __dxlog_file5,
|
|
1676
|
-
L: 184,
|
|
1677
|
-
S: this,
|
|
1678
|
-
C: (f, a) => f(...a)
|
|
1679
|
-
});
|
|
1680
|
-
const peer = this._getOrCreatePeer(swarmEvent.peerAvailable.peer);
|
|
1681
|
-
peer.advertizing = true;
|
|
1682
|
-
}
|
|
1683
|
-
} else if (swarmEvent.peerLeft) {
|
|
1684
|
-
const peer = this._peers.get(swarmEvent.peerLeft.peer);
|
|
1685
|
-
if (peer) {
|
|
1686
|
-
peer.advertizing = false;
|
|
1687
|
-
if (this._isConnectionEstablishmentInProgress(peer)) {
|
|
1688
|
-
(0, import_log4.log)(`destroying peer, state: ${peer.connection?.state}`, void 0, {
|
|
1689
|
-
F: __dxlog_file5,
|
|
1690
|
-
L: 195,
|
|
1691
|
-
S: this,
|
|
1692
|
-
C: (f, a) => f(...a)
|
|
1693
|
-
});
|
|
1694
|
-
void this._destroyPeer(swarmEvent.peerLeft.peer, "peer left").catch((err) => import_log4.log.catch(err, void 0, {
|
|
1695
|
-
F: __dxlog_file5,
|
|
1696
|
-
L: 196,
|
|
1697
|
-
S: this,
|
|
1698
|
-
C: (f, a) => f(...a)
|
|
1699
|
-
}));
|
|
1700
|
-
}
|
|
1701
|
-
} else {
|
|
1702
|
-
(0, import_log4.log)("received peerLeft but no peer found", {
|
|
1703
|
-
peer: swarmEvent.peerLeft.peer.peerKey
|
|
1704
|
-
}, {
|
|
1705
|
-
F: __dxlog_file5,
|
|
1706
|
-
L: 199,
|
|
1707
|
-
S: this,
|
|
1708
|
-
C: (f, a) => f(...a)
|
|
1709
|
-
});
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1712
|
-
this._topology.update();
|
|
1713
|
-
}
|
|
1714
|
-
async onOffer(message) {
|
|
1715
|
-
(0, import_log4.log)("offer", {
|
|
1716
|
-
message
|
|
1717
|
-
}, {
|
|
1718
|
-
F: __dxlog_file5,
|
|
1719
|
-
L: 208,
|
|
1720
|
-
S: this,
|
|
1721
|
-
C: (f, a) => f(...a)
|
|
1722
|
-
});
|
|
1723
|
-
if (this._ctx.disposed) {
|
|
1724
|
-
(0, import_log4.log)("ignored for disposed swarm", void 0, {
|
|
1725
|
-
F: __dxlog_file5,
|
|
1726
|
-
L: 210,
|
|
1727
|
-
S: this,
|
|
1728
|
-
C: (f, a) => f(...a)
|
|
1729
|
-
});
|
|
1730
|
-
return {
|
|
1731
|
-
accept: false
|
|
1732
|
-
};
|
|
1733
|
-
}
|
|
1734
|
-
(0, import_invariant3.invariant)(message.author, void 0, {
|
|
1735
|
-
F: __dxlog_file5,
|
|
1736
|
-
L: 215,
|
|
1737
|
-
S: this,
|
|
1738
|
-
A: [
|
|
1739
|
-
"message.author",
|
|
1740
|
-
""
|
|
1741
|
-
]
|
|
1742
|
-
});
|
|
1743
|
-
if (message.recipient.peerKey !== this._ownPeer.peerKey) {
|
|
1744
|
-
(0, import_log4.log)("rejecting offer with incorrect peerId", {
|
|
1745
|
-
message
|
|
1746
|
-
}, {
|
|
1747
|
-
F: __dxlog_file5,
|
|
1748
|
-
L: 217,
|
|
1749
|
-
S: this,
|
|
1750
|
-
C: (f, a) => f(...a)
|
|
1751
|
-
});
|
|
1752
|
-
return {
|
|
1753
|
-
accept: false
|
|
1754
|
-
};
|
|
1755
|
-
}
|
|
1756
|
-
if (!message.topic?.equals(this._topic)) {
|
|
1757
|
-
(0, import_log4.log)("rejecting offer with incorrect topic", {
|
|
1758
|
-
message
|
|
1759
|
-
}, {
|
|
1760
|
-
F: __dxlog_file5,
|
|
1761
|
-
L: 221,
|
|
1762
|
-
S: this,
|
|
1763
|
-
C: (f, a) => f(...a)
|
|
1764
|
-
});
|
|
1765
|
-
return {
|
|
1766
|
-
accept: false
|
|
1767
|
-
};
|
|
1768
|
-
}
|
|
1769
|
-
const peer = this._getOfferSenderPeer(message.author);
|
|
1770
|
-
const answer = await peer.onOffer(message);
|
|
1771
|
-
this._topology.update();
|
|
1772
|
-
return answer;
|
|
1773
|
-
}
|
|
1774
|
-
_getOfferSenderPeer(senderInfo) {
|
|
1775
|
-
const peer = this._getOrCreatePeer(senderInfo);
|
|
1776
|
-
const connectionState = peer.connection?.state;
|
|
1777
|
-
if (connectionState === ConnectionState.CLOSING || connectionState === ConnectionState.ABORTING) {
|
|
1778
|
-
this._peers.delete(peer.remoteInfo);
|
|
1779
|
-
this.disconnected.emit(peer.remoteInfo);
|
|
1780
|
-
return this._getOrCreatePeer(peer.remoteInfo);
|
|
1781
|
-
}
|
|
1782
|
-
return peer;
|
|
1783
|
-
}
|
|
1784
|
-
async onSignal(message) {
|
|
1785
|
-
(0, import_log4.log)("signal", {
|
|
1786
|
-
message
|
|
1787
|
-
}, {
|
|
1788
|
-
F: __dxlog_file5,
|
|
1789
|
-
L: 246,
|
|
1790
|
-
S: this,
|
|
1791
|
-
C: (f, a) => f(...a)
|
|
1792
|
-
});
|
|
1793
|
-
if (this._ctx.disposed) {
|
|
1794
|
-
import_log4.log.info("ignored for offline swarm", void 0, {
|
|
1795
|
-
F: __dxlog_file5,
|
|
1796
|
-
L: 248,
|
|
1797
|
-
S: this,
|
|
1798
|
-
C: (f, a) => f(...a)
|
|
1799
|
-
});
|
|
1800
|
-
return;
|
|
1801
|
-
}
|
|
1802
|
-
(0, import_invariant3.invariant)(message.recipient.peerKey === this._ownPeer.peerKey, `Invalid signal peer id expected=${this.ownPeerId}, actual=${message.recipient}`, {
|
|
1803
|
-
F: __dxlog_file5,
|
|
1804
|
-
L: 251,
|
|
1805
|
-
S: this,
|
|
1806
|
-
A: [
|
|
1807
|
-
"message.recipient.peerKey === this._ownPeer.peerKey",
|
|
1808
|
-
"`Invalid signal peer id expected=${this.ownPeerId}, actual=${message.recipient}`"
|
|
1809
|
-
]
|
|
1810
|
-
});
|
|
1811
|
-
(0, import_invariant3.invariant)(message.topic?.equals(this._topic), void 0, {
|
|
1812
|
-
F: __dxlog_file5,
|
|
1813
|
-
L: 255,
|
|
1814
|
-
S: this,
|
|
1815
|
-
A: [
|
|
1816
|
-
"message.topic?.equals(this._topic)",
|
|
1817
|
-
""
|
|
1818
|
-
]
|
|
1819
|
-
});
|
|
1820
|
-
(0, import_invariant3.invariant)(message.author, void 0, {
|
|
1821
|
-
F: __dxlog_file5,
|
|
1822
|
-
L: 256,
|
|
1823
|
-
S: this,
|
|
1824
|
-
A: [
|
|
1825
|
-
"message.author",
|
|
1826
|
-
""
|
|
1827
|
-
]
|
|
1828
|
-
});
|
|
1829
|
-
const peer = this._getOrCreatePeer(message.author);
|
|
1830
|
-
await peer.onSignal(message);
|
|
1831
|
-
}
|
|
1832
|
-
// For debug purposes
|
|
1833
|
-
async goOffline() {
|
|
1834
|
-
await this._ctx.dispose();
|
|
1835
|
-
await Promise.all([
|
|
1836
|
-
...this._peers.keys()
|
|
1837
|
-
].map((peerId) => this._destroyPeer(peerId, "goOffline")));
|
|
1838
|
-
}
|
|
1839
|
-
// For debug purposes
|
|
1840
|
-
async goOnline() {
|
|
1841
|
-
this._ctx = new import_context3.Context(void 0, {
|
|
1842
|
-
F: __dxlog_file5,
|
|
1843
|
-
L: 272
|
|
1844
|
-
});
|
|
1845
|
-
}
|
|
1846
|
-
_getOrCreatePeer(peerInfo) {
|
|
1847
|
-
(0, import_invariant3.invariant)(peerInfo.peerKey, "PeerInfo.peerKey is required", {
|
|
1848
|
-
F: __dxlog_file5,
|
|
1849
|
-
L: 276,
|
|
1850
|
-
S: this,
|
|
1851
|
-
A: [
|
|
1852
|
-
"peerInfo.peerKey",
|
|
1853
|
-
"'PeerInfo.peerKey is required'"
|
|
1854
|
-
]
|
|
1855
|
-
});
|
|
1856
|
-
let peer = this._peers.get(peerInfo);
|
|
1857
|
-
if (!peer) {
|
|
1858
|
-
peer = new Peer(peerInfo, this._topic, this._ownPeer, this._swarmMessenger, this._protocolProvider, this._transportFactory, this._connectionLimiter, {
|
|
1859
|
-
onInitiated: (connection) => {
|
|
1860
|
-
this.connectionAdded.emit(connection);
|
|
1861
|
-
},
|
|
1862
|
-
onConnected: () => {
|
|
1863
|
-
this.connected.emit(peerInfo);
|
|
1864
|
-
},
|
|
1865
|
-
onDisconnected: async () => {
|
|
1866
|
-
if (this._isUnregistered(peer)) {
|
|
1867
|
-
import_log4.log.verbose("ignored onDisconnected for unregistered peer", void 0, {
|
|
1868
|
-
F: __dxlog_file5,
|
|
1869
|
-
L: 296,
|
|
1870
|
-
S: this,
|
|
1871
|
-
C: (f, a) => f(...a)
|
|
1872
|
-
});
|
|
1873
|
-
return;
|
|
1874
|
-
}
|
|
1875
|
-
if (!peer.advertizing) {
|
|
1876
|
-
await this._destroyPeer(peerInfo, "peer disconnected");
|
|
1877
|
-
}
|
|
1878
|
-
this.disconnected.emit(peerInfo);
|
|
1879
|
-
this._topology.update();
|
|
1880
|
-
},
|
|
1881
|
-
onRejected: () => {
|
|
1882
|
-
if (!this._isUnregistered(peer)) {
|
|
1883
|
-
(0, import_log4.log)("peer rejected connection", {
|
|
1884
|
-
peerInfo
|
|
1885
|
-
}, {
|
|
1886
|
-
F: __dxlog_file5,
|
|
1887
|
-
L: 310,
|
|
1888
|
-
S: this,
|
|
1889
|
-
C: (f, a) => f(...a)
|
|
1890
|
-
});
|
|
1891
|
-
void this._destroyPeer(peerInfo, "peer rejected connection");
|
|
1892
|
-
}
|
|
1893
|
-
},
|
|
1894
|
-
onAccepted: () => {
|
|
1895
|
-
this._topology.update();
|
|
1896
|
-
},
|
|
1897
|
-
onOffer: (remoteId) => {
|
|
1898
|
-
return this._topology.onOffer(import_keys3.PublicKey.from(remoteId.peerKey));
|
|
1899
|
-
},
|
|
1900
|
-
onPeerAvailable: () => {
|
|
1901
|
-
this._topology.update();
|
|
1902
|
-
}
|
|
1903
|
-
});
|
|
1904
|
-
this._peers.set(peerInfo, peer);
|
|
1905
|
-
}
|
|
1906
|
-
return peer;
|
|
1907
|
-
}
|
|
1908
|
-
async _destroyPeer(peerInfo, reason) {
|
|
1909
|
-
(0, import_log4.log)("destroy peer", {
|
|
1910
|
-
peerKey: peerInfo.peerKey,
|
|
1911
|
-
reason
|
|
1912
|
-
}, {
|
|
1913
|
-
F: __dxlog_file5,
|
|
1914
|
-
L: 332,
|
|
1915
|
-
S: this,
|
|
1916
|
-
C: (f, a) => f(...a)
|
|
1917
|
-
});
|
|
1918
|
-
const peer = this._peers.get(peerInfo);
|
|
1919
|
-
(0, import_invariant3.invariant)(peer, void 0, {
|
|
1920
|
-
F: __dxlog_file5,
|
|
1921
|
-
L: 334,
|
|
1922
|
-
S: this,
|
|
1923
|
-
A: [
|
|
1924
|
-
"peer",
|
|
1925
|
-
""
|
|
1926
|
-
]
|
|
1927
|
-
});
|
|
1928
|
-
this._peers.delete(peerInfo);
|
|
1929
|
-
await peer.safeDestroy(reason);
|
|
1930
|
-
}
|
|
1931
|
-
_getSwarmController() {
|
|
1932
|
-
return {
|
|
1933
|
-
getState: () => ({
|
|
1934
|
-
ownPeerId: import_keys3.PublicKey.from(this._ownPeer.peerKey),
|
|
1935
|
-
connected: Array.from(this._peers.entries()).filter(([_, peer]) => peer.connection).map(([info]) => import_keys3.PublicKey.from(info.peerKey)),
|
|
1936
|
-
candidates: Array.from(this._peers.entries()).filter(([_, peer]) => !peer.connection && peer.advertizing && peer.availableToConnect).map(([info]) => import_keys3.PublicKey.from(info.peerKey)),
|
|
1937
|
-
allPeers: Array.from(this._peers.keys()).map((info) => import_keys3.PublicKey.from(info.peerKey))
|
|
1938
|
-
}),
|
|
1939
|
-
connect: (peer) => {
|
|
1940
|
-
if (this._ctx.disposed) {
|
|
1941
|
-
return;
|
|
1942
|
-
}
|
|
1943
|
-
(0, import_async3.scheduleTask)(this._ctx, async () => {
|
|
1944
|
-
try {
|
|
1945
|
-
await this._initiateConnection({
|
|
1946
|
-
peerKey: peer.toHex()
|
|
1947
|
-
});
|
|
1948
|
-
} catch (err) {
|
|
1949
|
-
(0, import_log4.log)("initiation error", err, {
|
|
1950
|
-
F: __dxlog_file5,
|
|
1951
|
-
L: 361,
|
|
1952
|
-
S: this,
|
|
1953
|
-
C: (f, a) => f(...a)
|
|
1954
|
-
});
|
|
1955
|
-
}
|
|
1956
|
-
});
|
|
1957
|
-
},
|
|
1958
|
-
disconnect: async (peer) => {
|
|
1959
|
-
if (this._ctx.disposed) {
|
|
1960
|
-
return;
|
|
1961
|
-
}
|
|
1962
|
-
(0, import_async3.scheduleTask)(this._ctx, async () => {
|
|
1963
|
-
await this._closeConnection({
|
|
1964
|
-
peerKey: peer.toHex()
|
|
1965
|
-
});
|
|
1966
|
-
this._topology.update();
|
|
1967
|
-
});
|
|
1968
|
-
}
|
|
1969
|
-
};
|
|
1970
|
-
}
|
|
1971
|
-
/**
|
|
1972
|
-
* Creates a connection then sends message over signal network.
|
|
1973
|
-
*/
|
|
1974
|
-
async _initiateConnection(remotePeer) {
|
|
1975
|
-
const ctx = this._ctx;
|
|
1976
|
-
const peer = this._getOrCreatePeer(remotePeer);
|
|
1977
|
-
if (remotePeer.peerKey < this._ownPeer.peerKey) {
|
|
1978
|
-
(0, import_log4.log)("initiation delay", {
|
|
1979
|
-
remotePeer
|
|
1980
|
-
}, {
|
|
1981
|
-
F: __dxlog_file5,
|
|
1982
|
-
L: 389,
|
|
1983
|
-
S: this,
|
|
1984
|
-
C: (f, a) => f(...a)
|
|
1985
|
-
});
|
|
1986
|
-
await (0, import_async3.sleep)(this._initiationDelay);
|
|
1987
|
-
}
|
|
1988
|
-
if (ctx.disposed) {
|
|
1989
|
-
return;
|
|
1990
|
-
}
|
|
1991
|
-
if (this._isUnregistered(peer)) {
|
|
1992
|
-
throw new Error("Peer left during initiation delay");
|
|
1993
|
-
}
|
|
1994
|
-
if (peer.connection) {
|
|
1995
|
-
return;
|
|
1996
|
-
}
|
|
1997
|
-
(0, import_log4.log)("initiating connection...", {
|
|
1998
|
-
remotePeer
|
|
1999
|
-
}, {
|
|
2000
|
-
F: __dxlog_file5,
|
|
2001
|
-
L: 405,
|
|
2002
|
-
S: this,
|
|
2003
|
-
C: (f, a) => f(...a)
|
|
2004
|
-
});
|
|
2005
|
-
await peer.initiateConnection();
|
|
2006
|
-
this._topology.update();
|
|
2007
|
-
(0, import_log4.log)("initiated", {
|
|
2008
|
-
remotePeer
|
|
2009
|
-
}, {
|
|
2010
|
-
F: __dxlog_file5,
|
|
2011
|
-
L: 408,
|
|
2012
|
-
S: this,
|
|
2013
|
-
C: (f, a) => f(...a)
|
|
2014
|
-
});
|
|
2015
|
-
}
|
|
2016
|
-
async _closeConnection(peerInfo) {
|
|
2017
|
-
const peer = this._peers.get(peerInfo);
|
|
2018
|
-
if (!peer) {
|
|
2019
|
-
return;
|
|
2020
|
-
}
|
|
2021
|
-
await peer.closeConnection();
|
|
2022
|
-
}
|
|
2023
|
-
_isConnectionEstablishmentInProgress(peer) {
|
|
2024
|
-
if (!peer.connection) {
|
|
2025
|
-
return true;
|
|
2026
|
-
}
|
|
2027
|
-
return [
|
|
2028
|
-
ConnectionState.INITIAL,
|
|
2029
|
-
ConnectionState.CREATED,
|
|
2030
|
-
ConnectionState.CONNECTING
|
|
2031
|
-
].includes(peer.connection.state);
|
|
2032
|
-
}
|
|
2033
|
-
_isUnregistered(peer) {
|
|
2034
|
-
return !peer || this._peers.get(peer.remoteInfo) !== peer;
|
|
2035
|
-
}
|
|
2036
|
-
};
|
|
2037
|
-
_ts_decorate3([
|
|
2038
|
-
import_log4.logInfo
|
|
2039
|
-
], Swarm.prototype, "_instanceId", void 0);
|
|
2040
|
-
_ts_decorate3([
|
|
2041
|
-
import_log4.logInfo
|
|
2042
|
-
], Swarm.prototype, "ownPeer", null);
|
|
2043
|
-
_ts_decorate3([
|
|
2044
|
-
import_log4.logInfo
|
|
2045
|
-
], Swarm.prototype, "topic", null);
|
|
2046
|
-
_ts_decorate3([
|
|
2047
|
-
import_async3.synchronized
|
|
2048
|
-
], Swarm.prototype, "onSwarmEvent", null);
|
|
2049
|
-
_ts_decorate3([
|
|
2050
|
-
import_async3.synchronized
|
|
2051
|
-
], Swarm.prototype, "onOffer", null);
|
|
2052
|
-
_ts_decorate3([
|
|
2053
|
-
import_async3.synchronized
|
|
2054
|
-
], Swarm.prototype, "goOffline", null);
|
|
2055
|
-
_ts_decorate3([
|
|
2056
|
-
import_async3.synchronized
|
|
2057
|
-
], Swarm.prototype, "goOnline", null);
|
|
2058
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/swarm/swarm-mapper.ts";
|
|
2059
|
-
var SwarmMapper = class {
|
|
2060
|
-
get peers() {
|
|
2061
|
-
return Array.from(this._peers.values());
|
|
2062
|
-
}
|
|
2063
|
-
constructor(_swarm) {
|
|
2064
|
-
this._swarm = _swarm;
|
|
2065
|
-
this._subscriptions = new import_async5.SubscriptionList();
|
|
2066
|
-
this._connectionSubscriptions = new import_util4.ComplexMap(import_messaging2.PeerInfoHash);
|
|
2067
|
-
this._peers = new import_util4.ComplexMap(import_messaging2.PeerInfoHash);
|
|
2068
|
-
this.mapUpdated = new import_async5.Event();
|
|
2069
|
-
this._subscriptions.add(_swarm.connectionAdded.on((connection) => {
|
|
2070
|
-
this._update();
|
|
2071
|
-
this._connectionSubscriptions.set(connection.remoteInfo, connection.stateChanged.on(() => {
|
|
2072
|
-
this._update();
|
|
2073
|
-
}));
|
|
2074
|
-
}));
|
|
2075
|
-
this._subscriptions.add(_swarm.disconnected.on((peerId) => {
|
|
2076
|
-
this._connectionSubscriptions.get(peerId)?.();
|
|
2077
|
-
this._connectionSubscriptions.delete(peerId);
|
|
2078
|
-
this._update();
|
|
2079
|
-
}));
|
|
2080
|
-
this._update();
|
|
2081
|
-
}
|
|
2082
|
-
_update() {
|
|
2083
|
-
(0, import_log6.log)("updating swarm", void 0, {
|
|
2084
|
-
F: __dxlog_file6,
|
|
2085
|
-
L: 71,
|
|
2086
|
-
S: this,
|
|
2087
|
-
C: (f, a) => f(...a)
|
|
2088
|
-
});
|
|
2089
|
-
this._peers.clear();
|
|
2090
|
-
this._peers.set(this._swarm.ownPeer, {
|
|
2091
|
-
id: this._swarm.ownPeerId,
|
|
2092
|
-
state: "ME",
|
|
2093
|
-
connections: []
|
|
2094
|
-
});
|
|
2095
|
-
for (const connection of this._swarm.connections) {
|
|
2096
|
-
this._peers.set(connection.remoteInfo, {
|
|
2097
|
-
id: import_keys5.PublicKey.from(connection.remoteInfo.peerKey),
|
|
2098
|
-
state: connection.state,
|
|
2099
|
-
connections: [
|
|
2100
|
-
this._swarm.ownPeerId
|
|
2101
|
-
]
|
|
2102
|
-
});
|
|
2103
|
-
}
|
|
2104
|
-
(0, import_log6.log)("graph changed", {
|
|
2105
|
-
directConnections: this._swarm.connections.length,
|
|
2106
|
-
totalPeersInSwarm: this._peers.size
|
|
2107
|
-
}, {
|
|
2108
|
-
F: __dxlog_file6,
|
|
2109
|
-
L: 112,
|
|
2110
|
-
S: this,
|
|
2111
|
-
C: (f, a) => f(...a)
|
|
2112
|
-
});
|
|
2113
|
-
this.mapUpdated.emit(Array.from(this._peers.values()));
|
|
2114
|
-
}
|
|
2115
|
-
// TODO(burdon): Async open/close.
|
|
2116
|
-
destroy() {
|
|
2117
|
-
Array.from(this._connectionSubscriptions.values()).forEach((cb) => cb());
|
|
2118
|
-
this._connectionSubscriptions.clear();
|
|
2119
|
-
this._subscriptions.clear();
|
|
2120
|
-
}
|
|
2121
|
-
};
|
|
2122
|
-
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/swarm/connection-limiter.ts";
|
|
2123
|
-
var MAX_CONCURRENT_INITIATING_CONNECTIONS = 50;
|
|
2124
|
-
var ConnectionLimiter = class {
|
|
2125
|
-
constructor({ maxConcurrentInitConnections = MAX_CONCURRENT_INITIATING_CONNECTIONS } = {}) {
|
|
2126
|
-
this._ctx = new import_context5.Context(void 0, {
|
|
2127
|
-
F: __dxlog_file7,
|
|
2128
|
-
L: 23
|
|
2129
|
-
});
|
|
2130
|
-
this._waitingPromises = new import_util5.ComplexMap(import_keys6.PublicKey.hash);
|
|
2131
|
-
this.resolveWaitingPromises = new import_async6.DeferredTask(this._ctx, async () => {
|
|
2132
|
-
Array.from(this._waitingPromises.values()).slice(0, this._maxConcurrentInitConnections).forEach(({ resolve }) => {
|
|
2133
|
-
resolve();
|
|
2134
|
-
});
|
|
2135
|
-
});
|
|
2136
|
-
this._maxConcurrentInitConnections = maxConcurrentInitConnections;
|
|
2137
|
-
}
|
|
2138
|
-
/**
|
|
2139
|
-
* @returns Promise that resolves in queue when connections amount with 'CONNECTING' state is below the limit.
|
|
2140
|
-
*/
|
|
2141
|
-
async connecting(sessionId) {
|
|
2142
|
-
(0, import_invariant5.invariant)(!this._waitingPromises.has(sessionId), "Peer is already waiting for connection", {
|
|
2143
|
-
F: __dxlog_file7,
|
|
2144
|
-
L: 48,
|
|
2145
|
-
S: this,
|
|
2146
|
-
A: [
|
|
2147
|
-
"!this._waitingPromises.has(sessionId)",
|
|
2148
|
-
"'Peer is already waiting for connection'"
|
|
2149
|
-
]
|
|
2150
|
-
});
|
|
2151
|
-
(0, import_log7.log)("waiting", {
|
|
2152
|
-
sessionId
|
|
2153
|
-
}, {
|
|
2154
|
-
F: __dxlog_file7,
|
|
2155
|
-
L: 49,
|
|
2156
|
-
S: this,
|
|
2157
|
-
C: (f, a) => f(...a)
|
|
2158
|
-
});
|
|
2159
|
-
await new Promise((resolve, reject) => {
|
|
2160
|
-
this._waitingPromises.set(sessionId, {
|
|
2161
|
-
resolve,
|
|
2162
|
-
reject
|
|
2163
|
-
});
|
|
2164
|
-
this.resolveWaitingPromises.schedule();
|
|
2165
|
-
});
|
|
2166
|
-
(0, import_log7.log)("allow", {
|
|
2167
|
-
sessionId
|
|
2168
|
-
}, {
|
|
2169
|
-
F: __dxlog_file7,
|
|
2170
|
-
L: 57,
|
|
2171
|
-
S: this,
|
|
2172
|
-
C: (f, a) => f(...a)
|
|
2173
|
-
});
|
|
2174
|
-
}
|
|
2175
|
-
/**
|
|
2176
|
-
* Rejects promise returned by `connecting` method.
|
|
2177
|
-
*/
|
|
2178
|
-
doneConnecting(sessionId) {
|
|
2179
|
-
(0, import_log7.log)("done", {
|
|
2180
|
-
sessionId
|
|
2181
|
-
}, {
|
|
2182
|
-
F: __dxlog_file7,
|
|
2183
|
-
L: 64,
|
|
2184
|
-
S: this,
|
|
2185
|
-
C: (f, a) => f(...a)
|
|
2186
|
-
});
|
|
2187
|
-
if (!this._waitingPromises.has(sessionId)) {
|
|
2188
|
-
return;
|
|
2189
|
-
}
|
|
2190
|
-
this._waitingPromises.get(sessionId).reject(new import_protocols5.CancelledError());
|
|
2191
|
-
this._waitingPromises.delete(sessionId);
|
|
2192
|
-
this.resolveWaitingPromises.schedule();
|
|
2193
|
-
}
|
|
2194
|
-
};
|
|
2195
|
-
var CONNECTION_GC_THRESHOLD = 1e3 * 60 * 15;
|
|
2196
|
-
var EventType = /* @__PURE__ */ function(EventType2) {
|
|
2197
|
-
EventType2["CONNECTION_STATE_CHANGED"] = "CONNECTION_STATE_CHANGED";
|
|
2198
|
-
EventType2["PROTOCOL_ERROR"] = "PROTOCOL_ERROR";
|
|
2199
|
-
EventType2["PROTOCOL_EXTENSIONS_INITIALIZED"] = "PROTOCOL_EXTENSIONS_INITIALIZED";
|
|
2200
|
-
EventType2["PROTOCOL_EXTENSIONS_HANDSHAKE"] = "PROTOCOL_EXTENSIONS_HANDSHAKE";
|
|
2201
|
-
EventType2["PROTOCOL_HANDSHAKE"] = "PROTOCOL_HANDSHAKE";
|
|
2202
|
-
return EventType2;
|
|
2203
|
-
}({});
|
|
2204
|
-
var ConnectionLog = class {
|
|
2205
|
-
constructor() {
|
|
2206
|
-
this._swarms = new import_util6.ComplexMap(import_keys7.PublicKey.hash);
|
|
2207
|
-
this.update = new import_async7.Event();
|
|
2208
|
-
}
|
|
2209
|
-
getSwarmInfo(swarmId) {
|
|
2210
|
-
return this._swarms.get(swarmId) ?? (0, import_debug3.raise)(new Error(`Swarm not found: ${swarmId}`));
|
|
2211
|
-
}
|
|
2212
|
-
get swarms() {
|
|
2213
|
-
return Array.from(this._swarms.values());
|
|
2214
|
-
}
|
|
2215
|
-
joinedSwarm(swarm) {
|
|
2216
|
-
const info = {
|
|
2217
|
-
id: import_keys7.PublicKey.from(swarm._instanceId),
|
|
2218
|
-
topic: swarm.topic,
|
|
2219
|
-
isActive: true,
|
|
2220
|
-
label: swarm.label,
|
|
2221
|
-
connections: []
|
|
2222
|
-
};
|
|
2223
|
-
this._swarms.set(import_keys7.PublicKey.from(swarm._instanceId), info);
|
|
2224
|
-
this.update.emit();
|
|
2225
|
-
swarm.connectionAdded.on((connection) => {
|
|
2226
|
-
const connectionInfo = {
|
|
2227
|
-
state: ConnectionState.CREATED,
|
|
2228
|
-
closeReason: connection.closeReason,
|
|
2229
|
-
remotePeerId: import_keys7.PublicKey.from(connection.remoteInfo.peerKey),
|
|
2230
|
-
sessionId: connection.sessionId,
|
|
2231
|
-
transport: connection.transport && Object.getPrototypeOf(connection.transport).constructor.name,
|
|
2232
|
-
protocolExtensions: [],
|
|
2233
|
-
events: [],
|
|
2234
|
-
lastUpdate: /* @__PURE__ */ new Date()
|
|
2235
|
-
};
|
|
2236
|
-
info.connections.push(connectionInfo);
|
|
2237
|
-
this.update.emit();
|
|
2238
|
-
connection.stateChanged.on(async (state) => {
|
|
2239
|
-
connectionInfo.state = state;
|
|
2240
|
-
connectionInfo.closeReason = connection.closeReason;
|
|
2241
|
-
connectionInfo.lastUpdate = /* @__PURE__ */ new Date();
|
|
2242
|
-
connectionInfo.events.push({
|
|
2243
|
-
type: "CONNECTION_STATE_CHANGED",
|
|
2244
|
-
newState: state
|
|
2245
|
-
});
|
|
2246
|
-
if (state === ConnectionState.CONNECTED) {
|
|
2247
|
-
const details = await connection.transport?.getDetails();
|
|
2248
|
-
connectionInfo.transportDetails = details;
|
|
2249
|
-
}
|
|
2250
|
-
this.update.emit();
|
|
2251
|
-
});
|
|
2252
|
-
connection.protocol?.stats?.on((stats) => {
|
|
2253
|
-
connectionInfo.readBufferSize = stats.readBufferSize;
|
|
2254
|
-
connectionInfo.writeBufferSize = stats.writeBufferSize;
|
|
2255
|
-
connectionInfo.streams = stats.channels;
|
|
2256
|
-
connectionInfo.lastUpdate = /* @__PURE__ */ new Date();
|
|
2257
|
-
this.update.emit();
|
|
2258
|
-
});
|
|
2259
|
-
connection.transportStats?.on((stats) => {
|
|
2260
|
-
connectionInfo.transportBytesSent = stats.bytesSent;
|
|
2261
|
-
connectionInfo.transportBytesReceived = stats.bytesReceived;
|
|
2262
|
-
connectionInfo.transportPacketsSent = stats.packetsSent;
|
|
2263
|
-
connectionInfo.transportPacketsReceived = stats.packetsReceived;
|
|
2264
|
-
});
|
|
2265
|
-
gcSwarm(info);
|
|
2266
|
-
});
|
|
2267
|
-
}
|
|
2268
|
-
leftSwarm(swarm) {
|
|
2269
|
-
this.getSwarmInfo(import_keys7.PublicKey.from(swarm._instanceId)).isActive = false;
|
|
2270
|
-
this.update.emit();
|
|
2271
|
-
}
|
|
2272
|
-
};
|
|
2273
|
-
var gcSwarm = (swarm) => {
|
|
2274
|
-
swarm.connections = swarm.connections?.filter((connection) => {
|
|
2275
|
-
return connection.lastUpdate ? Date.now() - connection.lastUpdate.getTime() < CONNECTION_GC_THRESHOLD : true;
|
|
2276
|
-
});
|
|
2277
|
-
};
|
|
2278
|
-
function _ts_decorate4(decorators, target, key, desc) {
|
|
2279
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2280
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2281
|
-
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;
|
|
2282
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2283
|
-
}
|
|
2284
|
-
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/network-manager.ts";
|
|
2285
|
-
var SwarmNetworkManager = class {
|
|
2286
|
-
constructor({ transportFactory, signalManager, enableDevtoolsLogging, peerInfo }) {
|
|
2287
|
-
this._swarms = new import_util7.ComplexMap(import_keys8.PublicKey.hash);
|
|
2288
|
-
this._mappers = new import_util7.ComplexMap(import_keys8.PublicKey.hash);
|
|
2289
|
-
this._instanceId = import_keys8.PublicKey.random().toHex();
|
|
2290
|
-
this._peerInfo = void 0;
|
|
2291
|
-
this._connectionState = import_services.ConnectionState.ONLINE;
|
|
2292
|
-
this.connectionStateChanged = new import_async8.Event();
|
|
2293
|
-
this.topicsUpdated = new import_async8.Event();
|
|
2294
|
-
this._transportFactory = transportFactory;
|
|
2295
|
-
this._signalManager = signalManager;
|
|
2296
|
-
this._signalManager.swarmEvent.on((event) => this._swarms.get(event.topic)?.onSwarmEvent(event));
|
|
2297
|
-
this._messenger = new import_messaging3.Messenger({
|
|
2298
|
-
signalManager: this._signalManager
|
|
2299
|
-
});
|
|
2300
|
-
this._signalConnection = {
|
|
2301
|
-
join: (opts) => this._signalManager.join(opts),
|
|
2302
|
-
leave: (opts) => this._signalManager.leave(opts)
|
|
2303
|
-
};
|
|
2304
|
-
this._peerInfo = peerInfo;
|
|
2305
|
-
this._connectionLimiter = new ConnectionLimiter();
|
|
2306
|
-
if (enableDevtoolsLogging) {
|
|
2307
|
-
this._connectionLog = new ConnectionLog();
|
|
2308
|
-
}
|
|
2309
|
-
}
|
|
2310
|
-
// TODO(burdon): Remove access (Devtools only).
|
|
2311
|
-
get connectionLog() {
|
|
2312
|
-
return this._connectionLog;
|
|
2313
|
-
}
|
|
2314
|
-
get connectionState() {
|
|
2315
|
-
return this._connectionState;
|
|
2316
|
-
}
|
|
2317
|
-
// TODO(burdon): Reconcile with "discovery_key".
|
|
2318
|
-
get topics() {
|
|
2319
|
-
return Array.from(this._swarms.keys());
|
|
2320
|
-
}
|
|
2321
|
-
getSwarmMap(topic) {
|
|
2322
|
-
return this._mappers.get(topic);
|
|
2323
|
-
}
|
|
2324
|
-
getSwarm(topic) {
|
|
2325
|
-
return this._swarms.get(topic);
|
|
2326
|
-
}
|
|
2327
|
-
setPeerInfo(peerInfo) {
|
|
2328
|
-
this._peerInfo = peerInfo;
|
|
2329
|
-
}
|
|
2330
|
-
async open() {
|
|
2331
|
-
import_log8.log.trace("dxos.mesh.network-manager.open", import_protocols6.trace.begin({
|
|
2332
|
-
id: this._instanceId
|
|
2333
|
-
}), {
|
|
2334
|
-
F: __dxlog_file8,
|
|
2335
|
-
L: 133,
|
|
2336
|
-
S: this,
|
|
2337
|
-
C: (f, a) => f(...a)
|
|
2338
|
-
});
|
|
2339
|
-
await this._messenger.open();
|
|
2340
|
-
await this._signalManager.open();
|
|
2341
|
-
import_log8.log.trace("dxos.mesh.network-manager.open", import_protocols6.trace.end({
|
|
2342
|
-
id: this._instanceId
|
|
2343
|
-
}), {
|
|
2344
|
-
F: __dxlog_file8,
|
|
2345
|
-
L: 136,
|
|
2346
|
-
S: this,
|
|
2347
|
-
C: (f, a) => f(...a)
|
|
2348
|
-
});
|
|
2349
|
-
}
|
|
2350
|
-
async close() {
|
|
2351
|
-
for (const topic of this._swarms.keys()) {
|
|
2352
|
-
await this.leaveSwarm(topic).catch((err) => {
|
|
2353
|
-
(0, import_log8.log)(err, void 0, {
|
|
2354
|
-
F: __dxlog_file8,
|
|
2355
|
-
L: 142,
|
|
2356
|
-
S: this,
|
|
2357
|
-
C: (f, a) => f(...a)
|
|
2358
|
-
});
|
|
2359
|
-
});
|
|
2360
|
-
}
|
|
2361
|
-
await this._messenger.close();
|
|
2362
|
-
await this._signalManager.close();
|
|
2363
|
-
}
|
|
2364
|
-
/**
|
|
2365
|
-
* Join the swarm.
|
|
2366
|
-
*/
|
|
2367
|
-
async joinSwarm({ topic, topology, protocolProvider: protocol, label }) {
|
|
2368
|
-
(0, import_invariant6.invariant)(import_keys8.PublicKey.isPublicKey(topic), void 0, {
|
|
2369
|
-
F: __dxlog_file8,
|
|
2370
|
-
L: 160,
|
|
2371
|
-
S: this,
|
|
2372
|
-
A: [
|
|
2373
|
-
"PublicKey.isPublicKey(topic)",
|
|
2374
|
-
""
|
|
2375
|
-
]
|
|
2376
|
-
});
|
|
2377
|
-
(0, import_invariant6.invariant)(topology, void 0, {
|
|
2378
|
-
F: __dxlog_file8,
|
|
2379
|
-
L: 161,
|
|
2380
|
-
S: this,
|
|
2381
|
-
A: [
|
|
2382
|
-
"topology",
|
|
2383
|
-
""
|
|
2384
|
-
]
|
|
2385
|
-
});
|
|
2386
|
-
(0, import_invariant6.invariant)(this._peerInfo, void 0, {
|
|
2387
|
-
F: __dxlog_file8,
|
|
2388
|
-
L: 162,
|
|
2389
|
-
S: this,
|
|
2390
|
-
A: [
|
|
2391
|
-
"this._peerInfo",
|
|
2392
|
-
""
|
|
2393
|
-
]
|
|
2394
|
-
});
|
|
2395
|
-
(0, import_invariant6.invariant)(typeof protocol === "function", void 0, {
|
|
2396
|
-
F: __dxlog_file8,
|
|
2397
|
-
L: 163,
|
|
2398
|
-
S: this,
|
|
2399
|
-
A: [
|
|
2400
|
-
"typeof protocol === 'function'",
|
|
2401
|
-
""
|
|
2402
|
-
]
|
|
2403
|
-
});
|
|
2404
|
-
if (this._swarms.has(topic)) {
|
|
2405
|
-
throw new Error(`Already connected to swarm: ${import_keys8.PublicKey.from(topic)}`);
|
|
2406
|
-
}
|
|
2407
|
-
(0, import_log8.log)("joining", {
|
|
2408
|
-
topic: import_keys8.PublicKey.from(topic),
|
|
2409
|
-
peerInfo: this._peerInfo,
|
|
2410
|
-
topology: topology.toString()
|
|
2411
|
-
}, {
|
|
2412
|
-
F: __dxlog_file8,
|
|
2413
|
-
L: 168,
|
|
2414
|
-
S: this,
|
|
2415
|
-
C: (f, a) => f(...a)
|
|
2416
|
-
});
|
|
2417
|
-
const swarm = new Swarm(topic, this._peerInfo, topology, protocol, this._messenger, this._transportFactory, label, this._connectionLimiter);
|
|
2418
|
-
swarm.errors.handle((error) => {
|
|
2419
|
-
(0, import_log8.log)("swarm error", {
|
|
2420
|
-
error
|
|
2421
|
-
}, {
|
|
2422
|
-
F: __dxlog_file8,
|
|
2423
|
-
L: 181,
|
|
2424
|
-
S: this,
|
|
2425
|
-
C: (f, a) => f(...a)
|
|
2426
|
-
});
|
|
2427
|
-
});
|
|
2428
|
-
this._swarms.set(topic, swarm);
|
|
2429
|
-
this._mappers.set(topic, new SwarmMapper(swarm));
|
|
2430
|
-
await swarm.open();
|
|
2431
|
-
this._signalConnection.join({
|
|
2432
|
-
topic,
|
|
2433
|
-
peer: this._peerInfo
|
|
2434
|
-
}).catch((error) => import_log8.log.catch(error, void 0, {
|
|
2435
|
-
F: __dxlog_file8,
|
|
2436
|
-
L: 190,
|
|
2437
|
-
S: this,
|
|
2438
|
-
C: (f, a) => f(...a)
|
|
2439
|
-
}));
|
|
2440
|
-
this.topicsUpdated.emit();
|
|
2441
|
-
this._connectionLog?.joinedSwarm(swarm);
|
|
2442
|
-
(0, import_log8.log)("joined", {
|
|
2443
|
-
topic: import_keys8.PublicKey.from(topic),
|
|
2444
|
-
count: this._swarms.size
|
|
2445
|
-
}, {
|
|
2446
|
-
F: __dxlog_file8,
|
|
2447
|
-
L: 194,
|
|
2448
|
-
S: this,
|
|
2449
|
-
C: (f, a) => f(...a)
|
|
2450
|
-
});
|
|
2451
|
-
return {
|
|
2452
|
-
close: () => this.leaveSwarm(topic)
|
|
2453
|
-
};
|
|
2454
|
-
}
|
|
2455
|
-
/**
|
|
2456
|
-
* Close the connection.
|
|
2457
|
-
*/
|
|
2458
|
-
async leaveSwarm(topic) {
|
|
2459
|
-
if (!this._swarms.has(topic)) {
|
|
2460
|
-
return;
|
|
2461
|
-
}
|
|
2462
|
-
(0, import_log8.log)("leaving", {
|
|
2463
|
-
topic: import_keys8.PublicKey.from(topic)
|
|
2464
|
-
}, {
|
|
2465
|
-
F: __dxlog_file8,
|
|
2466
|
-
L: 211,
|
|
2467
|
-
S: this,
|
|
2468
|
-
C: (f, a) => f(...a)
|
|
2469
|
-
});
|
|
2470
|
-
const swarm = this._swarms.get(topic);
|
|
2471
|
-
await this._signalConnection.leave({
|
|
2472
|
-
topic,
|
|
2473
|
-
peer: swarm.ownPeer
|
|
2474
|
-
});
|
|
2475
|
-
const map = this._mappers.get(topic);
|
|
2476
|
-
map.destroy();
|
|
2477
|
-
this._mappers.delete(topic);
|
|
2478
|
-
this._connectionLog?.leftSwarm(swarm);
|
|
2479
|
-
await swarm.destroy();
|
|
2480
|
-
this._swarms.delete(topic);
|
|
2481
|
-
this.topicsUpdated.emit();
|
|
2482
|
-
(0, import_log8.log)("left", {
|
|
2483
|
-
topic: import_keys8.PublicKey.from(topic),
|
|
2484
|
-
count: this._swarms.size
|
|
2485
|
-
}, {
|
|
2486
|
-
F: __dxlog_file8,
|
|
2487
|
-
L: 225,
|
|
2488
|
-
S: this,
|
|
2489
|
-
C: (f, a) => f(...a)
|
|
2490
|
-
});
|
|
2491
|
-
}
|
|
2492
|
-
async setConnectionState(state) {
|
|
2493
|
-
if (state === this._connectionState) {
|
|
2494
|
-
return;
|
|
2495
|
-
}
|
|
2496
|
-
switch (state) {
|
|
2497
|
-
case import_services.ConnectionState.OFFLINE: {
|
|
2498
|
-
this._connectionState = state;
|
|
2499
|
-
await Promise.all([
|
|
2500
|
-
...this._swarms.values()
|
|
2501
|
-
].map((swarm) => swarm.goOffline()));
|
|
2502
|
-
await this._messenger.close();
|
|
2503
|
-
await this._signalManager.close();
|
|
2504
|
-
break;
|
|
2505
|
-
}
|
|
2506
|
-
case import_services.ConnectionState.ONLINE: {
|
|
2507
|
-
this._connectionState = state;
|
|
2508
|
-
this._messenger.open();
|
|
2509
|
-
await Promise.all([
|
|
2510
|
-
...this._swarms.values()
|
|
2511
|
-
].map((swarm) => swarm.goOnline()));
|
|
2512
|
-
await this._signalManager.open();
|
|
2513
|
-
break;
|
|
2514
|
-
}
|
|
2515
|
-
}
|
|
2516
|
-
this.connectionStateChanged.emit(this._connectionState);
|
|
2517
|
-
}
|
|
2518
|
-
};
|
|
2519
|
-
_ts_decorate4([
|
|
2520
|
-
import_async8.synchronized
|
|
2521
|
-
], SwarmNetworkManager.prototype, "joinSwarm", null);
|
|
2522
|
-
_ts_decorate4([
|
|
2523
|
-
import_async8.synchronized
|
|
2524
|
-
], SwarmNetworkManager.prototype, "leaveSwarm", null);
|
|
2525
|
-
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/topology/fully-connected-topology.ts";
|
|
2526
|
-
var FullyConnectedTopology = class {
|
|
2527
|
-
toString() {
|
|
2528
|
-
return "FullyConnectedTopology";
|
|
2529
|
-
}
|
|
2530
|
-
init(controller) {
|
|
2531
|
-
(0, import_invariant7.invariant)(!this._controller, "Already initialized", {
|
|
2532
|
-
F: __dxlog_file9,
|
|
2533
|
-
L: 18,
|
|
2534
|
-
S: this,
|
|
2535
|
-
A: [
|
|
2536
|
-
"!this._controller",
|
|
2537
|
-
"'Already initialized'"
|
|
2538
|
-
]
|
|
2539
|
-
});
|
|
2540
|
-
this._controller = controller;
|
|
2541
|
-
}
|
|
2542
|
-
update() {
|
|
2543
|
-
(0, import_invariant7.invariant)(this._controller, "Not initialized", {
|
|
2544
|
-
F: __dxlog_file9,
|
|
2545
|
-
L: 23,
|
|
2546
|
-
S: this,
|
|
2547
|
-
A: [
|
|
2548
|
-
"this._controller",
|
|
2549
|
-
"'Not initialized'"
|
|
2550
|
-
]
|
|
2551
|
-
});
|
|
2552
|
-
const { candidates: discovered } = this._controller.getState();
|
|
2553
|
-
for (const peer of discovered) {
|
|
2554
|
-
this._controller.connect(peer);
|
|
2555
|
-
}
|
|
2556
|
-
}
|
|
2557
|
-
async onOffer(peer) {
|
|
2558
|
-
return true;
|
|
2559
|
-
}
|
|
2560
|
-
async destroy() {
|
|
2561
|
-
}
|
|
2562
|
-
};
|
|
2563
|
-
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/topology/mmst-topology.ts";
|
|
2564
|
-
var MIN_UPDATE_INTERVAL = 1e3 * 10;
|
|
2565
|
-
var MAX_CHANGES_PER_UPDATE = 1;
|
|
2566
|
-
var MMSTTopology = class {
|
|
2567
|
-
constructor({ originateConnections = 2, maxPeers = 4, sampleSize = 10 } = {}) {
|
|
2568
|
-
this._sampleCollected = false;
|
|
2569
|
-
this._lastAction = /* @__PURE__ */ new Date(0);
|
|
2570
|
-
this._originateConnections = originateConnections;
|
|
2571
|
-
this._maxPeers = maxPeers;
|
|
2572
|
-
this._sampleSize = sampleSize;
|
|
2573
|
-
}
|
|
2574
|
-
init(controller) {
|
|
2575
|
-
(0, import_invariant8.invariant)(!this._controller, "Already initialized", {
|
|
2576
|
-
F: __dxlog_file10,
|
|
2577
|
-
L: 49,
|
|
2578
|
-
S: this,
|
|
2579
|
-
A: [
|
|
2580
|
-
"!this._controller",
|
|
2581
|
-
"'Already initialized'"
|
|
2582
|
-
]
|
|
2583
|
-
});
|
|
2584
|
-
this._controller = controller;
|
|
2585
|
-
}
|
|
2586
|
-
update() {
|
|
2587
|
-
(0, import_invariant8.invariant)(this._controller, "Not initialized", {
|
|
2588
|
-
F: __dxlog_file10,
|
|
2589
|
-
L: 54,
|
|
2590
|
-
S: this,
|
|
2591
|
-
A: [
|
|
2592
|
-
"this._controller",
|
|
2593
|
-
"'Not initialized'"
|
|
2594
|
-
]
|
|
2595
|
-
});
|
|
2596
|
-
const { connected, candidates } = this._controller.getState();
|
|
2597
|
-
if (this._sampleCollected || connected.length > this._maxPeers || candidates.length > 0) {
|
|
2598
|
-
(0, import_log9.log)("Running the algorithm.", void 0, {
|
|
2599
|
-
F: __dxlog_file10,
|
|
2600
|
-
L: 58,
|
|
2601
|
-
S: this,
|
|
2602
|
-
C: (f, a) => f(...a)
|
|
2603
|
-
});
|
|
2604
|
-
this._sampleCollected = true;
|
|
2605
|
-
this._runAlgorithm();
|
|
2606
|
-
}
|
|
2607
|
-
}
|
|
2608
|
-
forceUpdate() {
|
|
2609
|
-
this._lastAction = /* @__PURE__ */ new Date(0);
|
|
2610
|
-
this.update();
|
|
2611
|
-
}
|
|
2612
|
-
async onOffer(peer) {
|
|
2613
|
-
(0, import_invariant8.invariant)(this._controller, "Not initialized", {
|
|
2614
|
-
F: __dxlog_file10,
|
|
2615
|
-
L: 70,
|
|
2616
|
-
S: this,
|
|
2617
|
-
A: [
|
|
2618
|
-
"this._controller",
|
|
2619
|
-
"'Not initialized'"
|
|
2620
|
-
]
|
|
2621
|
-
});
|
|
2622
|
-
const { connected } = this._controller.getState();
|
|
2623
|
-
const accept = connected.length < this._maxPeers;
|
|
2624
|
-
(0, import_log9.log)(`Offer ${peer} accept=${accept}`, void 0, {
|
|
2625
|
-
F: __dxlog_file10,
|
|
2626
|
-
L: 73,
|
|
2627
|
-
S: this,
|
|
2628
|
-
C: (f, a) => f(...a)
|
|
2629
|
-
});
|
|
2630
|
-
return accept;
|
|
2631
|
-
}
|
|
2632
|
-
async destroy() {
|
|
2633
|
-
}
|
|
2634
|
-
_runAlgorithm() {
|
|
2635
|
-
(0, import_invariant8.invariant)(this._controller, "Not initialized", {
|
|
2636
|
-
F: __dxlog_file10,
|
|
2637
|
-
L: 82,
|
|
2638
|
-
S: this,
|
|
2639
|
-
A: [
|
|
2640
|
-
"this._controller",
|
|
2641
|
-
"'Not initialized'"
|
|
2642
|
-
]
|
|
2643
|
-
});
|
|
2644
|
-
const { connected, candidates, ownPeerId } = this._controller.getState();
|
|
2645
|
-
if (connected.length > this._maxPeers) {
|
|
2646
|
-
(0, import_log9.log)(`disconnect ${connected.length - this._maxPeers} peers.`, void 0, {
|
|
2647
|
-
F: __dxlog_file10,
|
|
2648
|
-
L: 88,
|
|
2649
|
-
S: this,
|
|
2650
|
-
C: (f, a) => f(...a)
|
|
2651
|
-
});
|
|
2652
|
-
const sorted = sortByXorDistance(connected, ownPeerId).reverse().slice(0, this._maxPeers - connected.length);
|
|
2653
|
-
(0, import_invariant8.invariant)(sorted.length === 0, void 0, {
|
|
2654
|
-
F: __dxlog_file10,
|
|
2655
|
-
L: 92,
|
|
2656
|
-
S: this,
|
|
2657
|
-
A: [
|
|
2658
|
-
"sorted.length === 0",
|
|
2659
|
-
""
|
|
2660
|
-
]
|
|
2661
|
-
});
|
|
2662
|
-
if (sorted.length > MAX_CHANGES_PER_UPDATE) {
|
|
2663
|
-
(0, import_log9.log)(`want to disconnect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`, void 0, {
|
|
2664
|
-
F: __dxlog_file10,
|
|
2665
|
-
L: 95,
|
|
2666
|
-
S: this,
|
|
2667
|
-
C: (f, a) => f(...a)
|
|
2668
|
-
});
|
|
2669
|
-
}
|
|
2670
|
-
if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {
|
|
2671
|
-
for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {
|
|
2672
|
-
(0, import_log9.log)(`Disconnect ${peer}.`, void 0, {
|
|
2673
|
-
F: __dxlog_file10,
|
|
2674
|
-
L: 100,
|
|
2675
|
-
S: this,
|
|
2676
|
-
C: (f, a) => f(...a)
|
|
2677
|
-
});
|
|
2678
|
-
this._controller.disconnect(peer);
|
|
2679
|
-
}
|
|
2680
|
-
this._lastAction = /* @__PURE__ */ new Date();
|
|
2681
|
-
} else {
|
|
2682
|
-
(0, import_log9.log)("rate limited disconnect", void 0, {
|
|
2683
|
-
F: __dxlog_file10,
|
|
2684
|
-
L: 105,
|
|
2685
|
-
S: this,
|
|
2686
|
-
C: (f, a) => f(...a)
|
|
2687
|
-
});
|
|
2688
|
-
}
|
|
2689
|
-
} else if (connected.length < this._originateConnections) {
|
|
2690
|
-
(0, import_log9.log)(`connect ${this._originateConnections - connected.length} peers.`, void 0, {
|
|
2691
|
-
F: __dxlog_file10,
|
|
2692
|
-
L: 109,
|
|
2693
|
-
S: this,
|
|
2694
|
-
C: (f, a) => f(...a)
|
|
2695
|
-
});
|
|
2696
|
-
const sample = candidates.sort(() => Math.random() - 0.5).slice(0, this._sampleSize);
|
|
2697
|
-
const sorted = sortByXorDistance(sample, ownPeerId).slice(0, this._originateConnections - connected.length);
|
|
2698
|
-
if (sorted.length > MAX_CHANGES_PER_UPDATE) {
|
|
2699
|
-
(0, import_log9.log)(`want to connect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`, void 0, {
|
|
2700
|
-
F: __dxlog_file10,
|
|
2701
|
-
L: 114,
|
|
2702
|
-
S: this,
|
|
2703
|
-
C: (f, a) => f(...a)
|
|
2704
|
-
});
|
|
2705
|
-
}
|
|
2706
|
-
if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {
|
|
2707
|
-
for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {
|
|
2708
|
-
(0, import_log9.log)(`Connect ${peer}.`, void 0, {
|
|
2709
|
-
F: __dxlog_file10,
|
|
2710
|
-
L: 118,
|
|
2711
|
-
S: this,
|
|
2712
|
-
C: (f, a) => f(...a)
|
|
2713
|
-
});
|
|
2714
|
-
this._controller.connect(peer);
|
|
2715
|
-
}
|
|
2716
|
-
this._lastAction = /* @__PURE__ */ new Date();
|
|
2717
|
-
} else {
|
|
2718
|
-
(0, import_log9.log)("rate limited connect", void 0, {
|
|
2719
|
-
F: __dxlog_file10,
|
|
2720
|
-
L: 123,
|
|
2721
|
-
S: this,
|
|
2722
|
-
C: (f, a) => f(...a)
|
|
2723
|
-
});
|
|
2724
|
-
}
|
|
2725
|
-
}
|
|
2726
|
-
}
|
|
2727
|
-
toString() {
|
|
2728
|
-
return "MMSTTopology";
|
|
2729
|
-
}
|
|
2730
|
-
};
|
|
2731
|
-
var sortByXorDistance = (keys, reference) => {
|
|
2732
|
-
const sorted = keys.sort((a, b) => {
|
|
2733
|
-
return compareXor(distXor(a.asBuffer(), reference.asBuffer()), distXor(b.asBuffer(), reference.asBuffer()));
|
|
2734
|
-
});
|
|
2735
|
-
(0, import_log9.log)("Sorted keys", {
|
|
2736
|
-
keys,
|
|
2737
|
-
reference,
|
|
2738
|
-
sorted
|
|
2739
|
-
}, {
|
|
2740
|
-
F: __dxlog_file10,
|
|
2741
|
-
L: 137,
|
|
2742
|
-
S: void 0,
|
|
2743
|
-
C: (f, a) => f(...a)
|
|
2744
|
-
});
|
|
2745
|
-
return sorted;
|
|
2746
|
-
};
|
|
2747
|
-
var distXor = (a, b) => {
|
|
2748
|
-
const maxLength = Math.max(a.length, b.length);
|
|
2749
|
-
const result = Buffer.allocUnsafe(maxLength);
|
|
2750
|
-
for (let i = 0; i < maxLength; i++) {
|
|
2751
|
-
result[i] = (a[i] || 0) ^ (b[i] || 0);
|
|
2752
|
-
}
|
|
2753
|
-
return result;
|
|
2754
|
-
};
|
|
2755
|
-
var compareXor = (a, b) => {
|
|
2756
|
-
const maxLength = Math.max(a.length, b.length);
|
|
2757
|
-
for (let i = 0; i < maxLength; i++) {
|
|
2758
|
-
if ((a[i] || 0) === (b[i] || 0)) {
|
|
2759
|
-
continue;
|
|
2760
|
-
}
|
|
2761
|
-
return (a[i] || 0) < (b[i] || 0) ? -1 : 1;
|
|
2762
|
-
}
|
|
2763
|
-
return 0;
|
|
2764
|
-
};
|
|
2765
|
-
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/topology/star-topology.ts";
|
|
2766
|
-
var StarTopology = class {
|
|
2767
|
-
constructor(_centralPeer) {
|
|
2768
|
-
this._centralPeer = _centralPeer;
|
|
2769
|
-
}
|
|
2770
|
-
toString() {
|
|
2771
|
-
return `StarTopology(${this._centralPeer.truncate()})`;
|
|
2772
|
-
}
|
|
2773
|
-
init(controller) {
|
|
2774
|
-
(0, import_invariant9.invariant)(!this._controller, "Already initialized.", {
|
|
2775
|
-
F: __dxlog_file11,
|
|
2776
|
-
L: 21,
|
|
2777
|
-
S: this,
|
|
2778
|
-
A: [
|
|
2779
|
-
"!this._controller",
|
|
2780
|
-
"'Already initialized.'"
|
|
2781
|
-
]
|
|
2782
|
-
});
|
|
2783
|
-
this._controller = controller;
|
|
2784
|
-
}
|
|
2785
|
-
update() {
|
|
2786
|
-
(0, import_invariant9.invariant)(this._controller, "Not initialized.", {
|
|
2787
|
-
F: __dxlog_file11,
|
|
2788
|
-
L: 26,
|
|
2789
|
-
S: this,
|
|
2790
|
-
A: [
|
|
2791
|
-
"this._controller",
|
|
2792
|
-
"'Not initialized.'"
|
|
2793
|
-
]
|
|
2794
|
-
});
|
|
2795
|
-
const { candidates, connected, ownPeerId } = this._controller.getState();
|
|
2796
|
-
if (!ownPeerId.equals(this._centralPeer)) {
|
|
2797
|
-
(0, import_log10.log)("leaf peer dropping all connections apart from central peer.", void 0, {
|
|
2798
|
-
F: __dxlog_file11,
|
|
2799
|
-
L: 29,
|
|
2800
|
-
S: this,
|
|
2801
|
-
C: (f, a) => f(...a)
|
|
2802
|
-
});
|
|
2803
|
-
for (const peer of connected) {
|
|
2804
|
-
if (!peer.equals(this._centralPeer)) {
|
|
2805
|
-
(0, import_log10.log)("dropping connection", {
|
|
2806
|
-
peer
|
|
2807
|
-
}, {
|
|
2808
|
-
F: __dxlog_file11,
|
|
2809
|
-
L: 34,
|
|
2810
|
-
S: this,
|
|
2811
|
-
C: (f, a) => f(...a)
|
|
2812
|
-
});
|
|
2813
|
-
this._controller.disconnect(peer);
|
|
2814
|
-
}
|
|
2815
|
-
}
|
|
2816
|
-
}
|
|
2817
|
-
for (const peer of candidates) {
|
|
2818
|
-
if (peer.equals(this._centralPeer) || ownPeerId.equals(this._centralPeer)) {
|
|
2819
|
-
(0, import_log10.log)("connecting to peer", {
|
|
2820
|
-
peer
|
|
2821
|
-
}, {
|
|
2822
|
-
F: __dxlog_file11,
|
|
2823
|
-
L: 43,
|
|
2824
|
-
S: this,
|
|
2825
|
-
C: (f, a) => f(...a)
|
|
2826
|
-
});
|
|
2827
|
-
this._controller.connect(peer);
|
|
2828
|
-
}
|
|
2829
|
-
}
|
|
2830
|
-
}
|
|
2831
|
-
async onOffer(peer) {
|
|
2832
|
-
(0, import_invariant9.invariant)(this._controller, "Not initialized.", {
|
|
2833
|
-
F: __dxlog_file11,
|
|
2834
|
-
L: 50,
|
|
2835
|
-
S: this,
|
|
2836
|
-
A: [
|
|
2837
|
-
"this._controller",
|
|
2838
|
-
"'Not initialized.'"
|
|
2839
|
-
]
|
|
2840
|
-
});
|
|
2841
|
-
const { ownPeerId } = this._controller.getState();
|
|
2842
|
-
(0, import_log10.log)("offer", {
|
|
2843
|
-
peer,
|
|
2844
|
-
isCentral: peer.equals(this._centralPeer),
|
|
2845
|
-
isSelfCentral: ownPeerId.equals(this._centralPeer)
|
|
2846
|
-
}, {
|
|
2847
|
-
F: __dxlog_file11,
|
|
2848
|
-
L: 52,
|
|
2849
|
-
S: this,
|
|
2850
|
-
C: (f, a) => f(...a)
|
|
2851
|
-
});
|
|
2852
|
-
return ownPeerId.equals(this._centralPeer) || peer.equals(this._centralPeer);
|
|
2853
|
-
}
|
|
2854
|
-
async destroy() {
|
|
2855
|
-
}
|
|
2856
|
-
};
|
|
2857
|
-
function _ts_decorate5(decorators, target, key, desc) {
|
|
2858
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2859
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2860
|
-
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;
|
|
2861
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2862
|
-
}
|
|
2863
|
-
var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/memory-transport.ts";
|
|
2864
|
-
var MEMORY_TRANSPORT_DELAY = 1;
|
|
2865
|
-
var createStreamDelay = (delay) => {
|
|
2866
|
-
return new import_node_stream.Transform({
|
|
2867
|
-
objectMode: true,
|
|
2868
|
-
transform: (chunk, _, cb) => {
|
|
2869
|
-
setTimeout(() => cb(null, chunk), delay);
|
|
2870
|
-
}
|
|
2871
|
-
});
|
|
2872
|
-
};
|
|
2873
|
-
var MemoryTransportFactory = {
|
|
2874
|
-
createTransport: (options) => new MemoryTransport(options)
|
|
2875
|
-
};
|
|
2876
|
-
var MemoryTransport = class _MemoryTransport {
|
|
2877
|
-
static {
|
|
2878
|
-
this._connections = new import_util8.ComplexMap(import_keys9.PublicKey.hash);
|
|
2879
|
-
}
|
|
2880
|
-
constructor(_options) {
|
|
2881
|
-
this._options = _options;
|
|
2882
|
-
this._instanceId = import_keys9.PublicKey.random();
|
|
2883
|
-
this._remote = new import_async9.Trigger();
|
|
2884
|
-
this._outgoingDelay = createStreamDelay(MEMORY_TRANSPORT_DELAY);
|
|
2885
|
-
this._incomingDelay = createStreamDelay(MEMORY_TRANSPORT_DELAY);
|
|
2886
|
-
this._closed = false;
|
|
2887
|
-
this.closed = new import_async9.Event();
|
|
2888
|
-
this.connected = new import_async9.Event();
|
|
2889
|
-
this.errors = new import_debug4.ErrorStream();
|
|
2890
|
-
(0, import_invariant10.invariant)(!_MemoryTransport._connections.has(this._instanceId), "Duplicate memory connection", {
|
|
2891
|
-
F: __dxlog_file12,
|
|
2892
|
-
L: 64,
|
|
2893
|
-
S: this,
|
|
2894
|
-
A: [
|
|
2895
|
-
"!MemoryTransport._connections.has(this._instanceId)",
|
|
2896
|
-
"'Duplicate memory connection'"
|
|
2897
|
-
]
|
|
2898
|
-
});
|
|
2899
|
-
_MemoryTransport._connections.set(this._instanceId, this);
|
|
2900
|
-
}
|
|
2901
|
-
get isOpen() {
|
|
2902
|
-
return !this._closed;
|
|
2903
|
-
}
|
|
2904
|
-
async open() {
|
|
2905
|
-
(0, import_log11.log)("opening...", void 0, {
|
|
2906
|
-
F: __dxlog_file12,
|
|
2907
|
-
L: 74,
|
|
2908
|
-
S: this,
|
|
2909
|
-
C: (f, a) => f(...a)
|
|
2910
|
-
});
|
|
2911
|
-
if (this._options.initiator) {
|
|
2912
|
-
(0, import_log11.log)("sending signal", void 0, {
|
|
2913
|
-
F: __dxlog_file12,
|
|
2914
|
-
L: 78,
|
|
2915
|
-
S: this,
|
|
2916
|
-
C: (f, a) => f(...a)
|
|
2917
|
-
});
|
|
2918
|
-
try {
|
|
2919
|
-
await this._options.sendSignal({
|
|
2920
|
-
payload: {
|
|
2921
|
-
transportId: this._instanceId.toHex()
|
|
2922
|
-
}
|
|
2923
|
-
});
|
|
2924
|
-
} catch (err) {
|
|
2925
|
-
if (!this._closed) {
|
|
2926
|
-
this.errors.raise(toError(err));
|
|
2927
|
-
}
|
|
2928
|
-
}
|
|
2929
|
-
} else {
|
|
2930
|
-
this._remote.wait({
|
|
2931
|
-
timeout: this._options.timeout ?? 1e3
|
|
2932
|
-
}).then((remoteId) => {
|
|
2933
|
-
if (this._closed) {
|
|
2934
|
-
return;
|
|
2935
|
-
}
|
|
2936
|
-
this._remoteInstanceId = remoteId;
|
|
2937
|
-
this._remoteConnection = _MemoryTransport._connections.get(this._remoteInstanceId);
|
|
2938
|
-
if (!this._remoteConnection) {
|
|
2939
|
-
this._closed = true;
|
|
2940
|
-
this.closed.emit();
|
|
2941
|
-
return;
|
|
2942
|
-
}
|
|
2943
|
-
(0, import_invariant10.invariant)(!this._remoteConnection._remoteConnection, `Remote already connected: ${this._remoteInstanceId}`, {
|
|
2944
|
-
F: __dxlog_file12,
|
|
2945
|
-
L: 104,
|
|
2946
|
-
S: this,
|
|
2947
|
-
A: [
|
|
2948
|
-
"!this._remoteConnection._remoteConnection",
|
|
2949
|
-
"`Remote already connected: ${this._remoteInstanceId}`"
|
|
2950
|
-
]
|
|
2951
|
-
});
|
|
2952
|
-
this._remoteConnection._remoteConnection = this;
|
|
2953
|
-
this._remoteConnection._remoteInstanceId = this._instanceId;
|
|
2954
|
-
(0, import_log11.log)("connected", void 0, {
|
|
2955
|
-
F: __dxlog_file12,
|
|
2956
|
-
L: 108,
|
|
2957
|
-
S: this,
|
|
2958
|
-
C: (f, a) => f(...a)
|
|
2959
|
-
});
|
|
2960
|
-
this._options.stream.pipe(this._outgoingDelay).pipe(this._remoteConnection._options.stream).pipe(this._incomingDelay).pipe(this._options.stream);
|
|
2961
|
-
this.connected.emit();
|
|
2962
|
-
this._remoteConnection.connected.emit();
|
|
2963
|
-
}).catch((err) => {
|
|
2964
|
-
if (this._closed) {
|
|
2965
|
-
return;
|
|
2966
|
-
}
|
|
2967
|
-
this.errors.raise(err);
|
|
2968
|
-
});
|
|
2969
|
-
}
|
|
2970
|
-
return this;
|
|
2971
|
-
}
|
|
2972
|
-
async close() {
|
|
2973
|
-
(0, import_log11.log)("closing...", void 0, {
|
|
2974
|
-
F: __dxlog_file12,
|
|
2975
|
-
L: 130,
|
|
2976
|
-
S: this,
|
|
2977
|
-
C: (f, a) => f(...a)
|
|
2978
|
-
});
|
|
2979
|
-
this._closed = true;
|
|
2980
|
-
_MemoryTransport._connections.delete(this._instanceId);
|
|
2981
|
-
if (this._remoteConnection) {
|
|
2982
|
-
this._remoteConnection._closed = true;
|
|
2983
|
-
_MemoryTransport._connections.delete(this._remoteInstanceId);
|
|
2984
|
-
this._options.stream.unpipe(this._incomingDelay);
|
|
2985
|
-
this._incomingDelay.unpipe(this._remoteConnection._options.stream);
|
|
2986
|
-
this._remoteConnection._options.stream.unpipe(this._outgoingDelay);
|
|
2987
|
-
this._outgoingDelay.unpipe(this._options.stream);
|
|
2988
|
-
this._options.stream.unpipe(this._outgoingDelay);
|
|
2989
|
-
this._remoteConnection.closed.emit();
|
|
2990
|
-
this._remoteConnection._remoteConnection = void 0;
|
|
2991
|
-
this._remoteConnection = void 0;
|
|
2992
|
-
}
|
|
2993
|
-
this.closed.emit();
|
|
2994
|
-
(0, import_log11.log)("closed", void 0, {
|
|
2995
|
-
F: __dxlog_file12,
|
|
2996
|
-
L: 158,
|
|
2997
|
-
S: this,
|
|
2998
|
-
C: (f, a) => f(...a)
|
|
2999
|
-
});
|
|
3000
|
-
return this;
|
|
3001
|
-
}
|
|
3002
|
-
async onSignal({ payload }) {
|
|
3003
|
-
(0, import_log11.log)("received signal", {
|
|
3004
|
-
payload
|
|
3005
|
-
}, {
|
|
3006
|
-
F: __dxlog_file12,
|
|
3007
|
-
L: 163,
|
|
3008
|
-
S: this,
|
|
3009
|
-
C: (f, a) => f(...a)
|
|
3010
|
-
});
|
|
3011
|
-
if (!payload?.transportId) {
|
|
3012
|
-
return;
|
|
3013
|
-
}
|
|
3014
|
-
const transportId = payload.transportId;
|
|
3015
|
-
if (transportId) {
|
|
3016
|
-
const remoteId = import_keys9.PublicKey.fromHex(transportId);
|
|
3017
|
-
this._remote.wake(remoteId);
|
|
3018
|
-
}
|
|
3019
|
-
}
|
|
3020
|
-
async getDetails() {
|
|
3021
|
-
return this._instanceId.toHex();
|
|
3022
|
-
}
|
|
3023
|
-
async getStats() {
|
|
3024
|
-
return {
|
|
3025
|
-
bytesSent: 0,
|
|
3026
|
-
bytesReceived: 0,
|
|
3027
|
-
packetsSent: 0,
|
|
3028
|
-
packetsReceived: 0
|
|
3029
|
-
};
|
|
3030
|
-
}
|
|
3031
|
-
};
|
|
3032
|
-
_ts_decorate5([
|
|
3033
|
-
import_log11.logInfo
|
|
3034
|
-
], MemoryTransport.prototype, "_instanceId", void 0);
|
|
3035
|
-
_ts_decorate5([
|
|
3036
|
-
import_log11.logInfo
|
|
3037
|
-
], MemoryTransport.prototype, "_remoteInstanceId", void 0);
|
|
3038
|
-
var toError = (err) => err instanceof Error ? err : new Error(String(err));
|
|
3039
|
-
var TransportKind = /* @__PURE__ */ function(TransportKind2) {
|
|
3040
|
-
TransportKind2["WEB_RTC"] = "WEB-RTC";
|
|
3041
|
-
TransportKind2["WEB_RTC_PROXY"] = "WEB-RTC_PROXY";
|
|
3042
|
-
TransportKind2["MEMORY"] = "MEMORY";
|
|
3043
|
-
TransportKind2["TCP"] = "TCP";
|
|
3044
|
-
return TransportKind2;
|
|
3045
|
-
}({});
|
|
3046
|
-
var BrowserRtcConnectionFactory = class {
|
|
3047
|
-
async initialize() {
|
|
3048
|
-
}
|
|
3049
|
-
async onConnectionDestroyed() {
|
|
3050
|
-
}
|
|
3051
|
-
async createConnection(config) {
|
|
3052
|
-
return new RTCPeerConnection(config);
|
|
3053
|
-
}
|
|
3054
|
-
async initConnection(connection, info) {
|
|
3055
|
-
}
|
|
3056
|
-
};
|
|
3057
|
-
var NodeRtcConnectionFactory = class _NodeRtcConnectionFactory {
|
|
3058
|
-
static {
|
|
3059
|
-
this._createdConnections = 0;
|
|
3060
|
-
}
|
|
3061
|
-
static {
|
|
3062
|
-
this._cleanupMutex = new import_async10.Mutex();
|
|
3063
|
-
}
|
|
3064
|
-
// This should be inside the function to avoid triggering `eval` in the global scope.
|
|
3065
|
-
// eslint-disable-next-line no-new-func
|
|
3066
|
-
// TODO(burdon): Do imports here?
|
|
3067
|
-
async initialize() {
|
|
3068
|
-
}
|
|
3069
|
-
async onConnectionDestroyed() {
|
|
3070
|
-
return _NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
|
|
3071
|
-
if (--_NodeRtcConnectionFactory._createdConnections === 0) {
|
|
3072
|
-
(await import("#node-datachannel")).cleanup();
|
|
3073
|
-
}
|
|
3074
|
-
});
|
|
3075
|
-
}
|
|
3076
|
-
async createConnection(config) {
|
|
3077
|
-
return _NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
|
|
3078
|
-
const { RTCPeerConnection: RTCPeerConnection1 } = await import("#node-datachannel/polyfill");
|
|
3079
|
-
_NodeRtcConnectionFactory._createdConnections++;
|
|
3080
|
-
return new RTCPeerConnection1(config);
|
|
3081
|
-
});
|
|
3082
|
-
}
|
|
3083
|
-
async initConnection(connection, info) {
|
|
3084
|
-
if (info.initiator) {
|
|
3085
|
-
connection.onnegotiationneeded?.(null);
|
|
3086
|
-
}
|
|
3087
|
-
}
|
|
3088
|
-
};
|
|
3089
|
-
var getRtcConnectionFactory = () => {
|
|
3090
|
-
return typeof globalThis.RTCPeerConnection === "undefined" ? new NodeRtcConnectionFactory() : new BrowserRtcConnectionFactory();
|
|
3091
|
-
};
|
|
3092
|
-
var describeSelectedRemoteCandidate = async (connection) => {
|
|
3093
|
-
const stats = connection && await getRtcConnectionStats(connection);
|
|
3094
|
-
const rc = stats?.remoteCandidate;
|
|
3095
|
-
if (!rc) {
|
|
3096
|
-
return "unavailable";
|
|
3097
|
-
}
|
|
3098
|
-
if (rc.candidateType === "relay") {
|
|
3099
|
-
return `${rc.ip}:${rc.port} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
|
|
3100
|
-
}
|
|
3101
|
-
return `${rc.ip}:${rc.port} ${rc.candidateType}`;
|
|
3102
|
-
};
|
|
3103
|
-
var createRtcTransportStats = async (connection, topic) => {
|
|
3104
|
-
const stats = connection && await getRtcConnectionStats(connection, topic);
|
|
3105
|
-
if (!stats) {
|
|
3106
|
-
return {
|
|
3107
|
-
bytesSent: 0,
|
|
3108
|
-
bytesReceived: 0,
|
|
3109
|
-
packetsSent: 0,
|
|
3110
|
-
packetsReceived: 0,
|
|
3111
|
-
rawStats: {}
|
|
3112
|
-
};
|
|
3113
|
-
}
|
|
3114
|
-
return {
|
|
3115
|
-
bytesSent: stats.dataChannel?.bytesSent,
|
|
3116
|
-
bytesReceived: stats.dataChannel?.bytesReceived,
|
|
3117
|
-
packetsSent: 0,
|
|
3118
|
-
packetsReceived: 0,
|
|
3119
|
-
rawStats: stats.raw
|
|
3120
|
-
};
|
|
3121
|
-
};
|
|
3122
|
-
var getRtcConnectionStats = async (connection, channelTopic) => {
|
|
3123
|
-
const stats = await connection.getStats();
|
|
3124
|
-
const statsEntries = Array.from(stats.entries());
|
|
3125
|
-
const transport = statsEntries.find(([_, entry]) => entry.type === "transport")?.[1];
|
|
3126
|
-
const selectedCandidatePair = transport && statsEntries.find(([entryId]) => entryId === transport.selectedCandidatePairId)?.[1];
|
|
3127
|
-
const remoteCandidate = selectedCandidatePair && statsEntries.find(([entryId]) => entryId === selectedCandidatePair.remoteCandidateId)?.[1];
|
|
3128
|
-
const dataChannel = channelTopic && statsEntries.find(([_, entry]) => entry.type === "data-channel" && entry.label === channelTopic)?.[1];
|
|
3129
|
-
return {
|
|
3130
|
-
transport,
|
|
3131
|
-
selectedCandidatePair,
|
|
3132
|
-
dataChannel,
|
|
3133
|
-
remoteCandidate,
|
|
3134
|
-
raw: Object.fromEntries(stats)
|
|
3135
|
-
};
|
|
3136
|
-
};
|
|
3137
|
-
var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-channel.ts";
|
|
3138
|
-
var MAX_MESSAGE_SIZE = 64 * 1024;
|
|
3139
|
-
var MAX_BUFFERED_AMOUNT = 64 * 1024;
|
|
3140
|
-
var RtcTransportChannel = class extends import_context6.Resource {
|
|
3141
|
-
constructor(_connection, _options) {
|
|
3142
|
-
super(), this._connection = _connection, this._options = _options, this.closed = new import_async12.Event(), this.connected = new import_async12.Event(), this.errors = new import_debug5.ErrorStream(), this._streamDataFlushedCallback = null, this._isChannelCreationInProgress = false;
|
|
3143
|
-
}
|
|
3144
|
-
get isRtcChannelCreationInProgress() {
|
|
3145
|
-
return this._isChannelCreationInProgress;
|
|
3146
|
-
}
|
|
3147
|
-
onConnectionError(error) {
|
|
3148
|
-
if (this.isOpen) {
|
|
3149
|
-
this.errors.raise(error);
|
|
3150
|
-
}
|
|
3151
|
-
}
|
|
3152
|
-
async _open() {
|
|
3153
|
-
(0, import_invariant12.invariant)(!this._isChannelCreationInProgress, void 0, {
|
|
3154
|
-
F: __dxlog_file13,
|
|
3155
|
-
L: 56,
|
|
3156
|
-
S: this,
|
|
3157
|
-
A: [
|
|
3158
|
-
"!this._isChannelCreationInProgress",
|
|
3159
|
-
""
|
|
3160
|
-
]
|
|
3161
|
-
});
|
|
3162
|
-
this._isChannelCreationInProgress = true;
|
|
3163
|
-
this._connection.createDataChannel(this._options.topic).then((channel) => {
|
|
3164
|
-
if (this.isOpen) {
|
|
3165
|
-
this._channel = channel;
|
|
3166
|
-
this._initChannel(this._channel);
|
|
3167
|
-
} else {
|
|
3168
|
-
this._safeCloseChannel(channel);
|
|
3169
|
-
}
|
|
3170
|
-
}).catch((err) => {
|
|
3171
|
-
if (this.isOpen) {
|
|
3172
|
-
const error = err instanceof Error ? err : new import_protocols8.ConnectivityError(`Failed to create a channel: ${JSON.stringify(err?.message)}`);
|
|
3173
|
-
this.errors.raise(error);
|
|
3174
|
-
} else {
|
|
3175
|
-
import_log13.log.verbose("connection establishment failed after transport was closed", {
|
|
3176
|
-
err
|
|
3177
|
-
}, {
|
|
3178
|
-
F: __dxlog_file13,
|
|
3179
|
-
L: 76,
|
|
3180
|
-
S: this,
|
|
3181
|
-
C: (f, a) => f(...a)
|
|
3182
|
-
});
|
|
3183
|
-
}
|
|
3184
|
-
}).finally(() => {
|
|
3185
|
-
this._isChannelCreationInProgress = false;
|
|
3186
|
-
});
|
|
3187
|
-
}
|
|
3188
|
-
async _close() {
|
|
3189
|
-
if (this._channel) {
|
|
3190
|
-
this._safeCloseChannel(this._channel);
|
|
3191
|
-
this._channel = void 0;
|
|
3192
|
-
this._stream = void 0;
|
|
3193
|
-
}
|
|
3194
|
-
this.closed.emit();
|
|
3195
|
-
(0, import_log13.log)("closed", void 0, {
|
|
3196
|
-
F: __dxlog_file13,
|
|
3197
|
-
L: 92,
|
|
3198
|
-
S: this,
|
|
3199
|
-
C: (f, a) => f(...a)
|
|
3200
|
-
});
|
|
3201
|
-
}
|
|
3202
|
-
_initChannel(channel) {
|
|
3203
|
-
Object.assign(channel, {
|
|
3204
|
-
onopen: () => {
|
|
3205
|
-
if (!this.isOpen) {
|
|
3206
|
-
import_log13.log.warn("channel opened in a closed transport", {
|
|
3207
|
-
topic: this._options.topic
|
|
3208
|
-
}, {
|
|
3209
|
-
F: __dxlog_file13,
|
|
3210
|
-
L: 99,
|
|
3211
|
-
S: this,
|
|
3212
|
-
C: (f, a) => f(...a)
|
|
3213
|
-
});
|
|
3214
|
-
this._safeCloseChannel(channel);
|
|
3215
|
-
return;
|
|
3216
|
-
}
|
|
3217
|
-
(0, import_log13.log)("onopen", void 0, {
|
|
3218
|
-
F: __dxlog_file13,
|
|
3219
|
-
L: 104,
|
|
3220
|
-
S: this,
|
|
3221
|
-
C: (f, a) => f(...a)
|
|
3222
|
-
});
|
|
3223
|
-
const duplex = new import_node_stream2.Duplex({
|
|
3224
|
-
read: () => {
|
|
3225
|
-
},
|
|
3226
|
-
write: (chunk, encoding, callback) => {
|
|
3227
|
-
return this._handleChannelWrite(chunk, callback);
|
|
3228
|
-
}
|
|
3229
|
-
});
|
|
3230
|
-
duplex.pipe(this._options.stream).pipe(duplex);
|
|
3231
|
-
this._stream = duplex;
|
|
3232
|
-
this.connected.emit();
|
|
3233
|
-
},
|
|
3234
|
-
onclose: async () => {
|
|
3235
|
-
(0, import_log13.log)("onclose", void 0, {
|
|
3236
|
-
F: __dxlog_file13,
|
|
3237
|
-
L: 117,
|
|
3238
|
-
S: this,
|
|
3239
|
-
C: (f, a) => f(...a)
|
|
3240
|
-
});
|
|
3241
|
-
await this.close();
|
|
3242
|
-
},
|
|
3243
|
-
onmessage: async (event) => {
|
|
3244
|
-
if (!this._stream) {
|
|
3245
|
-
import_log13.log.warn("ignoring message on a closed channel", void 0, {
|
|
3246
|
-
F: __dxlog_file13,
|
|
3247
|
-
L: 123,
|
|
3248
|
-
S: this,
|
|
3249
|
-
C: (f, a) => f(...a)
|
|
3250
|
-
});
|
|
3251
|
-
return;
|
|
3252
|
-
}
|
|
3253
|
-
let data = event.data;
|
|
3254
|
-
if (data instanceof ArrayBuffer) {
|
|
3255
|
-
data = Buffer.from(data);
|
|
3256
|
-
} else if (data instanceof Blob) {
|
|
3257
|
-
data = Buffer.from(await data.arrayBuffer());
|
|
3258
|
-
}
|
|
3259
|
-
this._stream.push(data);
|
|
3260
|
-
},
|
|
3261
|
-
onerror: (event) => {
|
|
3262
|
-
if (this.isOpen) {
|
|
3263
|
-
const err = event.error instanceof Error ? event.error : new Error(`Datachannel error: ${event.type}.`);
|
|
3264
|
-
this.errors.raise(err);
|
|
3265
|
-
}
|
|
3266
|
-
},
|
|
3267
|
-
onbufferedamountlow: () => {
|
|
3268
|
-
const cb = this._streamDataFlushedCallback;
|
|
3269
|
-
this._streamDataFlushedCallback = null;
|
|
3270
|
-
cb?.();
|
|
3271
|
-
}
|
|
3272
|
-
});
|
|
3273
|
-
}
|
|
3274
|
-
async _handleChannelWrite(chunk, callback) {
|
|
3275
|
-
if (!this._channel) {
|
|
3276
|
-
import_log13.log.warn("writing to a channel after a connection was closed", void 0, {
|
|
3277
|
-
F: __dxlog_file13,
|
|
3278
|
-
L: 153,
|
|
3279
|
-
S: this,
|
|
3280
|
-
C: (f, a) => f(...a)
|
|
3281
|
-
});
|
|
3282
|
-
return;
|
|
3283
|
-
}
|
|
3284
|
-
if (chunk.length > MAX_MESSAGE_SIZE) {
|
|
3285
|
-
const error = new Error(`Message too large: ${chunk.length} > ${MAX_MESSAGE_SIZE}.`);
|
|
3286
|
-
this.errors.raise(error);
|
|
3287
|
-
callback();
|
|
3288
|
-
return;
|
|
3289
|
-
}
|
|
3290
|
-
try {
|
|
3291
|
-
this._channel.send(chunk);
|
|
3292
|
-
} catch (err) {
|
|
3293
|
-
this.errors.raise(err);
|
|
3294
|
-
callback();
|
|
3295
|
-
return;
|
|
3296
|
-
}
|
|
3297
|
-
if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {
|
|
3298
|
-
if (this._streamDataFlushedCallback !== null) {
|
|
3299
|
-
import_log13.log.error("consumer trying to write before we are ready for more data", void 0, {
|
|
3300
|
-
F: __dxlog_file13,
|
|
3301
|
-
L: 174,
|
|
3302
|
-
S: this,
|
|
3303
|
-
C: (f, a) => f(...a)
|
|
3304
|
-
});
|
|
3305
|
-
}
|
|
3306
|
-
this._streamDataFlushedCallback = callback;
|
|
3307
|
-
} else {
|
|
3308
|
-
callback();
|
|
3309
|
-
}
|
|
3310
|
-
}
|
|
3311
|
-
_safeCloseChannel(channel) {
|
|
3312
|
-
try {
|
|
3313
|
-
channel.close();
|
|
3314
|
-
} catch (error) {
|
|
3315
|
-
import_log13.log.catch(error, void 0, {
|
|
3316
|
-
F: __dxlog_file13,
|
|
3317
|
-
L: 186,
|
|
3318
|
-
S: this,
|
|
3319
|
-
C: (f, a) => f(...a)
|
|
3320
|
-
});
|
|
3321
|
-
}
|
|
3322
|
-
}
|
|
3323
|
-
onSignal(signal) {
|
|
3324
|
-
return this._connection.onSignal(signal);
|
|
3325
|
-
}
|
|
3326
|
-
async getDetails() {
|
|
3327
|
-
return describeSelectedRemoteCandidate(this._connection.currentConnection);
|
|
3328
|
-
}
|
|
3329
|
-
async getStats() {
|
|
3330
|
-
return createRtcTransportStats(this._connection.currentConnection, this._options.topic);
|
|
3331
|
-
}
|
|
3332
|
-
};
|
|
3333
|
-
var chooseInitiatorPeer = (peer1Key, peer2Key) => peer1Key < peer2Key ? peer1Key : peer2Key;
|
|
3334
|
-
var areSdpEqual = (sdp1, sdp2) => {
|
|
3335
|
-
const sdp1Lines = deduplicatedSdpLines(sdp1);
|
|
3336
|
-
const sdp2Lines = deduplicatedSdpLines(sdp2);
|
|
3337
|
-
if (sdp1Lines.length !== sdp2Lines.length) {
|
|
3338
|
-
return false;
|
|
3339
|
-
}
|
|
3340
|
-
return sdp1Lines.every((line, idx) => line === sdp2Lines[idx]);
|
|
3341
|
-
};
|
|
3342
|
-
var deduplicatedSdpLines = (sdp) => {
|
|
3343
|
-
const deduplicatedLines = [];
|
|
3344
|
-
const seenLines = [];
|
|
3345
|
-
for (const line of sdp.split("\r\n")) {
|
|
3346
|
-
if (line.startsWith("m")) {
|
|
3347
|
-
seenLines.length = 0;
|
|
3348
|
-
}
|
|
3349
|
-
if (seenLines.includes(line)) {
|
|
3350
|
-
continue;
|
|
3351
|
-
}
|
|
3352
|
-
seenLines.push(line);
|
|
3353
|
-
deduplicatedLines.push(line);
|
|
3354
|
-
}
|
|
3355
|
-
return deduplicatedLines;
|
|
3356
|
-
};
|
|
3357
|
-
function _ts_decorate6(decorators, target, key, desc) {
|
|
3358
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3359
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3360
|
-
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;
|
|
3361
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3362
|
-
}
|
|
3363
|
-
var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-peer-connection.ts";
|
|
3364
|
-
var RtcPeerConnection = class {
|
|
3365
|
-
constructor(_factory, _options) {
|
|
3366
|
-
this._factory = _factory;
|
|
3367
|
-
this._options = _options;
|
|
3368
|
-
this._channelCreatedCallbacks = /* @__PURE__ */ new Map();
|
|
3369
|
-
this._transportChannels = /* @__PURE__ */ new Map();
|
|
3370
|
-
this._dataChannels = /* @__PURE__ */ new Map();
|
|
3371
|
-
this._readyForCandidates = new import_async11.Trigger();
|
|
3372
|
-
this._offerProcessingMutex = new import_async11.Mutex();
|
|
3373
|
-
this._initiator = chooseInitiatorPeer(_options.ownPeerKey, _options.remotePeerKey) === _options.ownPeerKey;
|
|
3374
|
-
}
|
|
3375
|
-
get transportChannelCount() {
|
|
3376
|
-
return this._transportChannels.size;
|
|
3377
|
-
}
|
|
3378
|
-
get currentConnection() {
|
|
3379
|
-
return this._connection;
|
|
3380
|
-
}
|
|
3381
|
-
async createDataChannel(topic) {
|
|
3382
|
-
const connection = await this._openConnection();
|
|
3383
|
-
if (!this._transportChannels.has(topic)) {
|
|
3384
|
-
if (!this._transportChannels.size) {
|
|
3385
|
-
void this._lockAndCloseConnection();
|
|
3386
|
-
}
|
|
3387
|
-
throw new Error("Transport closed while connection was being open");
|
|
3388
|
-
}
|
|
3389
|
-
if (this._initiator) {
|
|
3390
|
-
const channel = connection.createDataChannel(topic);
|
|
3391
|
-
this._dataChannels.set(topic, channel);
|
|
3392
|
-
return channel;
|
|
3393
|
-
} else {
|
|
3394
|
-
const existingChannel = this._dataChannels.get(topic);
|
|
3395
|
-
if (existingChannel) {
|
|
3396
|
-
return existingChannel;
|
|
3397
|
-
}
|
|
3398
|
-
(0, import_log12.log)("waiting for initiator-peer to open a data channel", void 0, {
|
|
3399
|
-
F: __dxlog_file14,
|
|
3400
|
-
L: 95,
|
|
3401
|
-
S: this,
|
|
3402
|
-
C: (f, a) => f(...a)
|
|
3403
|
-
});
|
|
3404
|
-
return new Promise((resolve, reject) => {
|
|
3405
|
-
this._channelCreatedCallbacks.set(topic, {
|
|
3406
|
-
resolve,
|
|
3407
|
-
reject
|
|
3408
|
-
});
|
|
3409
|
-
});
|
|
3410
|
-
}
|
|
3411
|
-
}
|
|
3412
|
-
createTransportChannel(options) {
|
|
3413
|
-
const channel = new RtcTransportChannel(this, options);
|
|
3414
|
-
this._transportChannels.set(options.topic, channel);
|
|
3415
|
-
channel.closed.on(() => {
|
|
3416
|
-
this._transportChannels.delete(options.topic);
|
|
3417
|
-
if (this._transportChannels.size === 0) {
|
|
3418
|
-
void this._lockAndCloseConnection();
|
|
3419
|
-
}
|
|
3420
|
-
});
|
|
3421
|
-
return channel;
|
|
3422
|
-
}
|
|
3423
|
-
async _openConnection() {
|
|
3424
|
-
if (this._connection) {
|
|
3425
|
-
return this._connection;
|
|
3426
|
-
}
|
|
3427
|
-
(0, import_log12.log)("initializing connection...", () => ({
|
|
3428
|
-
remotePeer: this._options.remotePeerKey
|
|
3429
|
-
}), {
|
|
3430
|
-
F: __dxlog_file14,
|
|
3431
|
-
L: 120,
|
|
3432
|
-
S: this,
|
|
3433
|
-
C: (f, a) => f(...a)
|
|
3434
|
-
});
|
|
3435
|
-
const config = await this._loadConnectionConfig();
|
|
3436
|
-
const connection = await this._factory.createConnection(config);
|
|
3437
|
-
const iceCandidateErrors = [];
|
|
3438
|
-
Object.assign(connection, {
|
|
3439
|
-
onnegotiationneeded: async () => {
|
|
3440
|
-
(0, import_invariant11.invariant)(this._initiator, void 0, {
|
|
3441
|
-
F: __dxlog_file14,
|
|
3442
|
-
L: 135,
|
|
3443
|
-
S: this,
|
|
3444
|
-
A: [
|
|
3445
|
-
"this._initiator",
|
|
3446
|
-
""
|
|
3447
|
-
]
|
|
3448
|
-
});
|
|
3449
|
-
if (connection !== this._connection) {
|
|
3450
|
-
this._onConnectionCallbackAfterClose("onnegotiationneeded", connection);
|
|
3451
|
-
return;
|
|
3452
|
-
}
|
|
3453
|
-
(0, import_log12.log)("onnegotiationneeded", void 0, {
|
|
3454
|
-
F: __dxlog_file14,
|
|
3455
|
-
L: 142,
|
|
3456
|
-
S: this,
|
|
3457
|
-
C: (f, a) => f(...a)
|
|
3458
|
-
});
|
|
3459
|
-
try {
|
|
3460
|
-
const offer = await connection.createOffer();
|
|
3461
|
-
await connection.setLocalDescription(offer);
|
|
3462
|
-
await this._sendDescription(connection, offer);
|
|
3463
|
-
} catch (err) {
|
|
3464
|
-
void this._lockAndAbort(connection, err);
|
|
3465
|
-
}
|
|
3466
|
-
},
|
|
3467
|
-
// When ICE candidate identified (should be sent to remote peer) and when ICE gathering finalized.
|
|
3468
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidate_event
|
|
3469
|
-
onicecandidate: async (event) => {
|
|
3470
|
-
if (connection !== this._connection) {
|
|
3471
|
-
this._onConnectionCallbackAfterClose("onicecandidate", connection);
|
|
3472
|
-
return;
|
|
3473
|
-
}
|
|
3474
|
-
if (event.candidate) {
|
|
3475
|
-
(0, import_log12.log)("onicecandidate", {
|
|
3476
|
-
candidate: event.candidate.candidate
|
|
3477
|
-
}, {
|
|
3478
|
-
F: __dxlog_file14,
|
|
3479
|
-
L: 161,
|
|
3480
|
-
S: this,
|
|
3481
|
-
C: (f, a) => f(...a)
|
|
3482
|
-
});
|
|
3483
|
-
await this._sendIceCandidate(event.candidate);
|
|
3484
|
-
} else {
|
|
3485
|
-
(0, import_log12.log)("onicecandidate gathering complete", void 0, {
|
|
3486
|
-
F: __dxlog_file14,
|
|
3487
|
-
L: 164,
|
|
3488
|
-
S: this,
|
|
3489
|
-
C: (f, a) => f(...a)
|
|
3490
|
-
});
|
|
3491
|
-
}
|
|
3492
|
-
},
|
|
3493
|
-
// When error occurs while performing ICE negotiations through a STUN or TURN server.
|
|
3494
|
-
// It's ok for some candidates to fail if a working pair is eventually found.
|
|
3495
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidateerror_event
|
|
3496
|
-
onicecandidateerror: (event) => {
|
|
3497
|
-
const { url, errorCode, errorText } = event;
|
|
3498
|
-
iceCandidateErrors.push({
|
|
3499
|
-
url,
|
|
3500
|
-
errorCode,
|
|
3501
|
-
errorText
|
|
3502
|
-
});
|
|
3503
|
-
},
|
|
3504
|
-
// When possible error during ICE gathering.
|
|
3505
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceconnectionstatechange_event
|
|
3506
|
-
oniceconnectionstatechange: () => {
|
|
3507
|
-
if (connection !== this._connection) {
|
|
3508
|
-
this._onConnectionCallbackAfterClose("oniceconnectionstatechange", connection);
|
|
3509
|
-
return;
|
|
3510
|
-
}
|
|
3511
|
-
(0, import_log12.log)("oniceconnectionstatechange", {
|
|
3512
|
-
state: connection.iceConnectionState
|
|
3513
|
-
}, {
|
|
3514
|
-
F: __dxlog_file14,
|
|
3515
|
-
L: 184,
|
|
3516
|
-
S: this,
|
|
3517
|
-
C: (f, a) => f(...a)
|
|
3518
|
-
});
|
|
3519
|
-
if (connection.iceConnectionState === "failed") {
|
|
3520
|
-
void this._lockAndAbort(connection, createIceFailureError(iceCandidateErrors));
|
|
3521
|
-
}
|
|
3522
|
-
},
|
|
3523
|
-
// When new track (or channel) is added.
|
|
3524
|
-
// State: { new, connecting, connected, disconnected, failed, closed }
|
|
3525
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionstatechange_event
|
|
3526
|
-
onconnectionstatechange: () => {
|
|
3527
|
-
if (connection !== this._connection) {
|
|
3528
|
-
if (connection.connectionState !== "closed" && connection.connectionState !== "failed") {
|
|
3529
|
-
this._onConnectionCallbackAfterClose("onconnectionstatechange", connection);
|
|
3530
|
-
}
|
|
3531
|
-
return;
|
|
3532
|
-
}
|
|
3533
|
-
(0, import_log12.log)("onconnectionstatechange", {
|
|
3534
|
-
state: connection.connectionState
|
|
3535
|
-
}, {
|
|
3536
|
-
F: __dxlog_file14,
|
|
3537
|
-
L: 201,
|
|
3538
|
-
S: this,
|
|
3539
|
-
C: (f, a) => f(...a)
|
|
3540
|
-
});
|
|
3541
|
-
if (connection.connectionState === "failed") {
|
|
3542
|
-
void this._lockAndAbort(connection, new Error("Connection failed."));
|
|
3543
|
-
}
|
|
3544
|
-
},
|
|
3545
|
-
onsignalingstatechange: () => {
|
|
3546
|
-
(0, import_log12.log)("onsignalingstatechange", {
|
|
3547
|
-
state: connection.signalingState
|
|
3548
|
-
}, {
|
|
3549
|
-
F: __dxlog_file14,
|
|
3550
|
-
L: 208,
|
|
3551
|
-
S: this,
|
|
3552
|
-
C: (f, a) => f(...a)
|
|
3553
|
-
});
|
|
3554
|
-
},
|
|
3555
|
-
// When channel is added to connection.
|
|
3556
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/datachannel_event
|
|
3557
|
-
ondatachannel: (event) => {
|
|
3558
|
-
(0, import_invariant11.invariant)(!this._initiator, "Initiator is expected to create data channels.", {
|
|
3559
|
-
F: __dxlog_file14,
|
|
3560
|
-
L: 214,
|
|
3561
|
-
S: this,
|
|
3562
|
-
A: [
|
|
3563
|
-
"!this._initiator",
|
|
3564
|
-
"'Initiator is expected to create data channels.'"
|
|
3565
|
-
]
|
|
3566
|
-
});
|
|
3567
|
-
if (connection !== this._connection) {
|
|
3568
|
-
this._onConnectionCallbackAfterClose("ondatachannel", connection);
|
|
3569
|
-
return;
|
|
3570
|
-
}
|
|
3571
|
-
(0, import_log12.log)("ondatachannel", {
|
|
3572
|
-
label: event.channel.label
|
|
3573
|
-
}, {
|
|
3574
|
-
F: __dxlog_file14,
|
|
3575
|
-
L: 221,
|
|
3576
|
-
S: this,
|
|
3577
|
-
C: (f, a) => f(...a)
|
|
3578
|
-
});
|
|
3579
|
-
this._dataChannels.set(event.channel.label, event.channel);
|
|
3580
|
-
const pendingCallback = this._channelCreatedCallbacks.get(event.channel.label);
|
|
3581
|
-
if (pendingCallback) {
|
|
3582
|
-
this._channelCreatedCallbacks.delete(event.channel.label);
|
|
3583
|
-
pendingCallback.resolve(event.channel);
|
|
3584
|
-
}
|
|
3585
|
-
}
|
|
3586
|
-
});
|
|
3587
|
-
this._connection = connection;
|
|
3588
|
-
this._readyForCandidates.reset();
|
|
3589
|
-
await this._factory.initConnection(connection, {
|
|
3590
|
-
initiator: this._initiator
|
|
3591
|
-
});
|
|
3592
|
-
return this._connection;
|
|
3593
|
-
}
|
|
3594
|
-
async _lockAndAbort(connection, error) {
|
|
3595
|
-
this._abortConnection(connection, error);
|
|
3596
|
-
}
|
|
3597
|
-
_abortConnection(connection, error) {
|
|
3598
|
-
if (connection !== this._connection) {
|
|
3599
|
-
import_log12.log.error("attempted to abort an inactive connection", {
|
|
3600
|
-
error
|
|
3601
|
-
}, {
|
|
3602
|
-
F: __dxlog_file14,
|
|
3603
|
-
L: 246,
|
|
3604
|
-
S: this,
|
|
3605
|
-
C: (f, a) => f(...a)
|
|
3606
|
-
});
|
|
3607
|
-
this._safeCloseConnection(connection);
|
|
3608
|
-
return;
|
|
3609
|
-
}
|
|
3610
|
-
for (const [topic, pendingCallback] of this._channelCreatedCallbacks.entries()) {
|
|
3611
|
-
pendingCallback.reject(error);
|
|
3612
|
-
this._transportChannels.delete(topic);
|
|
3613
|
-
}
|
|
3614
|
-
this._channelCreatedCallbacks.clear();
|
|
3615
|
-
for (const channel of this._transportChannels.values()) {
|
|
3616
|
-
channel.onConnectionError(error);
|
|
3617
|
-
}
|
|
3618
|
-
this._transportChannels.clear();
|
|
3619
|
-
this._safeCloseConnection();
|
|
3620
|
-
(0, import_log12.log)("connection aborted", {
|
|
3621
|
-
reason: error.message
|
|
3622
|
-
}, {
|
|
3623
|
-
F: __dxlog_file14,
|
|
3624
|
-
L: 260,
|
|
3625
|
-
S: this,
|
|
3626
|
-
C: (f, a) => f(...a)
|
|
3627
|
-
});
|
|
3628
|
-
}
|
|
3629
|
-
async _lockAndCloseConnection() {
|
|
3630
|
-
(0, import_invariant11.invariant)(this._transportChannels.size === 0, void 0, {
|
|
3631
|
-
F: __dxlog_file14,
|
|
3632
|
-
L: 265,
|
|
3633
|
-
S: this,
|
|
3634
|
-
A: [
|
|
3635
|
-
"this._transportChannels.size === 0",
|
|
3636
|
-
""
|
|
3637
|
-
]
|
|
3638
|
-
});
|
|
3639
|
-
if (this._connection) {
|
|
3640
|
-
this._safeCloseConnection();
|
|
3641
|
-
(0, import_log12.log)("connection closed", void 0, {
|
|
3642
|
-
F: __dxlog_file14,
|
|
3643
|
-
L: 268,
|
|
3644
|
-
S: this,
|
|
3645
|
-
C: (f, a) => f(...a)
|
|
3646
|
-
});
|
|
3647
|
-
}
|
|
3648
|
-
}
|
|
3649
|
-
async onSignal(signal) {
|
|
3650
|
-
const connection = this._connection;
|
|
3651
|
-
if (!connection) {
|
|
3652
|
-
import_log12.log.warn("a signal ignored because the connection was closed", {
|
|
3653
|
-
type: signal.payload.data.type
|
|
3654
|
-
}, {
|
|
3655
|
-
F: __dxlog_file14,
|
|
3656
|
-
L: 276,
|
|
3657
|
-
S: this,
|
|
3658
|
-
C: (f, a) => f(...a)
|
|
3659
|
-
});
|
|
3660
|
-
return;
|
|
3661
|
-
}
|
|
3662
|
-
const data = signal.payload.data;
|
|
3663
|
-
switch (data.type) {
|
|
3664
|
-
case "offer": {
|
|
3665
|
-
await this._offerProcessingMutex.executeSynchronized(async () => {
|
|
3666
|
-
if (isRemoteDescriptionSet(connection, data)) {
|
|
3667
|
-
return;
|
|
3668
|
-
}
|
|
3669
|
-
if (connection.connectionState !== "new") {
|
|
3670
|
-
this._abortConnection(connection, new Error(`Received an offer in ${connection.connectionState}.`));
|
|
3671
|
-
return;
|
|
3672
|
-
}
|
|
3673
|
-
try {
|
|
3674
|
-
await connection.setRemoteDescription({
|
|
3675
|
-
type: data.type,
|
|
3676
|
-
sdp: data.sdp
|
|
3677
|
-
});
|
|
3678
|
-
const answer = await connection.createAnswer();
|
|
3679
|
-
await connection.setLocalDescription(answer);
|
|
3680
|
-
await this._sendDescription(connection, answer);
|
|
3681
|
-
this._onSessionNegotiated(connection);
|
|
3682
|
-
} catch (err) {
|
|
3683
|
-
this._abortConnection(connection, new Error("Error handling a remote offer.", {
|
|
3684
|
-
cause: err
|
|
3685
|
-
}));
|
|
3686
|
-
}
|
|
3687
|
-
});
|
|
3688
|
-
break;
|
|
3689
|
-
}
|
|
3690
|
-
case "answer":
|
|
3691
|
-
await this._offerProcessingMutex.executeSynchronized(async () => {
|
|
3692
|
-
try {
|
|
3693
|
-
if (isRemoteDescriptionSet(connection, data)) {
|
|
3694
|
-
return;
|
|
3695
|
-
}
|
|
3696
|
-
if (connection.signalingState !== "have-local-offer") {
|
|
3697
|
-
this._abortConnection(connection, new Error(`Unexpected answer from remote peer, signalingState was ${connection.signalingState}.`));
|
|
3698
|
-
return;
|
|
3699
|
-
}
|
|
3700
|
-
await connection.setRemoteDescription({
|
|
3701
|
-
type: data.type,
|
|
3702
|
-
sdp: data.sdp
|
|
3703
|
-
});
|
|
3704
|
-
this._onSessionNegotiated(connection);
|
|
3705
|
-
} catch (err) {
|
|
3706
|
-
this._abortConnection(connection, new Error("Error handling a remote answer.", {
|
|
3707
|
-
cause: err
|
|
3708
|
-
}));
|
|
3709
|
-
}
|
|
3710
|
-
});
|
|
3711
|
-
break;
|
|
3712
|
-
case "candidate":
|
|
3713
|
-
void this._processIceCandidate(connection, data.candidate);
|
|
3714
|
-
break;
|
|
3715
|
-
default:
|
|
3716
|
-
this._abortConnection(connection, new Error(`Unknown signal type ${data.type}.`));
|
|
3717
|
-
break;
|
|
3718
|
-
}
|
|
3719
|
-
(0, import_log12.log)("signal processed", {
|
|
3720
|
-
type: data.type
|
|
3721
|
-
}, {
|
|
3722
|
-
F: __dxlog_file14,
|
|
3723
|
-
L: 335,
|
|
3724
|
-
S: this,
|
|
3725
|
-
C: (f, a) => f(...a)
|
|
3726
|
-
});
|
|
3727
|
-
}
|
|
3728
|
-
async _processIceCandidate(connection, candidate) {
|
|
3729
|
-
try {
|
|
3730
|
-
await this._readyForCandidates.wait();
|
|
3731
|
-
if (connection === this._connection) {
|
|
3732
|
-
(0, import_log12.log)("adding ice candidate", {
|
|
3733
|
-
candidate
|
|
3734
|
-
}, {
|
|
3735
|
-
F: __dxlog_file14,
|
|
3736
|
-
L: 343,
|
|
3737
|
-
S: this,
|
|
3738
|
-
C: (f, a) => f(...a)
|
|
3739
|
-
});
|
|
3740
|
-
await connection.addIceCandidate(candidate);
|
|
3741
|
-
}
|
|
3742
|
-
} catch (err) {
|
|
3743
|
-
import_log12.log.catch(err, void 0, {
|
|
3744
|
-
F: __dxlog_file14,
|
|
3745
|
-
L: 347,
|
|
3746
|
-
S: this,
|
|
3747
|
-
C: (f, a) => f(...a)
|
|
3748
|
-
});
|
|
3749
|
-
}
|
|
3750
|
-
}
|
|
3751
|
-
_onSessionNegotiated(connection) {
|
|
3752
|
-
if (connection === this._connection) {
|
|
3753
|
-
(0, import_log12.log)("ready to process ice candidates", void 0, {
|
|
3754
|
-
F: __dxlog_file14,
|
|
3755
|
-
L: 353,
|
|
3756
|
-
S: this,
|
|
3757
|
-
C: (f, a) => f(...a)
|
|
3758
|
-
});
|
|
3759
|
-
this._readyForCandidates.wake();
|
|
3760
|
-
} else {
|
|
3761
|
-
import_log12.log.warn("session was negotiated after connection became inactive", void 0, {
|
|
3762
|
-
F: __dxlog_file14,
|
|
3763
|
-
L: 356,
|
|
3764
|
-
S: this,
|
|
3765
|
-
C: (f, a) => f(...a)
|
|
3766
|
-
});
|
|
3767
|
-
}
|
|
3768
|
-
}
|
|
3769
|
-
_onConnectionCallbackAfterClose(callback, connection) {
|
|
3770
|
-
import_log12.log.warn("callback invoked after a connection was destroyed, this is probably a bug", {
|
|
3771
|
-
callback,
|
|
3772
|
-
state: connection.connectionState
|
|
3773
|
-
}, {
|
|
3774
|
-
F: __dxlog_file14,
|
|
3775
|
-
L: 361,
|
|
3776
|
-
S: this,
|
|
3777
|
-
C: (f, a) => f(...a)
|
|
3778
|
-
});
|
|
3779
|
-
this._safeCloseConnection(connection);
|
|
3780
|
-
}
|
|
3781
|
-
_safeCloseConnection(connection = this._connection) {
|
|
3782
|
-
const resetFields = this._connection && connection === this._connection;
|
|
3783
|
-
try {
|
|
3784
|
-
connection?.close();
|
|
3785
|
-
} catch (err) {
|
|
3786
|
-
import_log12.log.catch(err, void 0, {
|
|
3787
|
-
F: __dxlog_file14,
|
|
3788
|
-
L: 373,
|
|
3789
|
-
S: this,
|
|
3790
|
-
C: (f, a) => f(...a)
|
|
3791
|
-
});
|
|
3792
|
-
}
|
|
3793
|
-
if (resetFields) {
|
|
3794
|
-
this._connection = void 0;
|
|
3795
|
-
this._dataChannels.clear();
|
|
3796
|
-
this._readyForCandidates.wake();
|
|
3797
|
-
void this._factory.onConnectionDestroyed().catch((err) => import_log12.log.catch(err, void 0, {
|
|
3798
|
-
F: __dxlog_file14,
|
|
3799
|
-
L: 379,
|
|
3800
|
-
S: this,
|
|
3801
|
-
C: (f, a) => f(...a)
|
|
3802
|
-
}));
|
|
3803
|
-
for (const [_, pendingCallback] of this._channelCreatedCallbacks.entries()) {
|
|
3804
|
-
pendingCallback.reject("Connection closed.");
|
|
3805
|
-
}
|
|
3806
|
-
this._channelCreatedCallbacks.clear();
|
|
3807
|
-
}
|
|
3808
|
-
}
|
|
3809
|
-
async _loadConnectionConfig() {
|
|
3810
|
-
const config = {
|
|
3811
|
-
...this._options.webrtcConfig
|
|
3812
|
-
};
|
|
3813
|
-
try {
|
|
3814
|
-
const providedIceServers = await this._options.iceProvider?.getIceServers() ?? [];
|
|
3815
|
-
if (providedIceServers.length > 0) {
|
|
3816
|
-
config.iceServers = [
|
|
3817
|
-
...config.iceServers ?? [],
|
|
3818
|
-
...providedIceServers
|
|
3819
|
-
];
|
|
3820
|
-
}
|
|
3821
|
-
} catch (error) {
|
|
3822
|
-
import_log12.log.catch(error, void 0, {
|
|
3823
|
-
F: __dxlog_file14,
|
|
3824
|
-
L: 395,
|
|
3825
|
-
S: this,
|
|
3826
|
-
C: (f, a) => f(...a)
|
|
3827
|
-
});
|
|
3828
|
-
}
|
|
3829
|
-
return config;
|
|
3830
|
-
}
|
|
3831
|
-
async _sendIceCandidate(candidate) {
|
|
3832
|
-
try {
|
|
3833
|
-
await this._options.sendSignal({
|
|
3834
|
-
payload: {
|
|
3835
|
-
data: {
|
|
3836
|
-
type: "candidate",
|
|
3837
|
-
candidate: {
|
|
3838
|
-
candidate: candidate.candidate,
|
|
3839
|
-
// These fields never seem to be not null, but connecting to Chrome doesn't work if they are.
|
|
3840
|
-
sdpMLineIndex: candidate.sdpMLineIndex ?? "0",
|
|
3841
|
-
sdpMid: candidate.sdpMid ?? "0"
|
|
3842
|
-
}
|
|
3843
|
-
}
|
|
3844
|
-
}
|
|
3845
|
-
});
|
|
3846
|
-
} catch (err) {
|
|
3847
|
-
import_log12.log.warn("signaling error", {
|
|
3848
|
-
err
|
|
3849
|
-
}, {
|
|
3850
|
-
F: __dxlog_file14,
|
|
3851
|
-
L: 416,
|
|
3852
|
-
S: this,
|
|
3853
|
-
C: (f, a) => f(...a)
|
|
3854
|
-
});
|
|
3855
|
-
}
|
|
3856
|
-
}
|
|
3857
|
-
async _sendDescription(connection, description) {
|
|
3858
|
-
if (connection !== this._connection) {
|
|
3859
|
-
return;
|
|
3860
|
-
}
|
|
3861
|
-
const data = {
|
|
3862
|
-
type: description.type,
|
|
3863
|
-
sdp: description.sdp
|
|
3864
|
-
};
|
|
3865
|
-
await this._options.sendSignal({
|
|
3866
|
-
payload: {
|
|
3867
|
-
data
|
|
3868
|
-
}
|
|
3869
|
-
});
|
|
3870
|
-
}
|
|
3871
|
-
get _connectionInfo() {
|
|
3872
|
-
const connectionInfo = this._connection && {
|
|
3873
|
-
connectionState: this._connection.connectionState,
|
|
3874
|
-
iceConnectionState: this._connection.iceConnectionState,
|
|
3875
|
-
iceGatheringState: this._connection.iceGatheringState,
|
|
3876
|
-
signalingState: this._connection.signalingState,
|
|
3877
|
-
remoteDescription: this._connection.remoteDescription,
|
|
3878
|
-
localDescription: this._connection.localDescription
|
|
3879
|
-
};
|
|
3880
|
-
return {
|
|
3881
|
-
...connectionInfo,
|
|
3882
|
-
ts: Date.now(),
|
|
3883
|
-
remotePeerKey: this._options.remotePeerKey,
|
|
3884
|
-
channels: [
|
|
3885
|
-
...this._transportChannels.keys()
|
|
3886
|
-
].map((topic) => topic),
|
|
3887
|
-
config: this._connection?.getConfiguration()
|
|
3888
|
-
};
|
|
3889
|
-
}
|
|
3890
|
-
get _loggerContext() {
|
|
3891
|
-
return {
|
|
3892
|
-
ownPeerKey: this._options.ownPeerKey,
|
|
3893
|
-
remotePeerKey: this._options.remotePeerKey,
|
|
3894
|
-
initiator: this._initiator,
|
|
3895
|
-
channels: this._transportChannels.size
|
|
3896
|
-
};
|
|
3897
|
-
}
|
|
3898
|
-
};
|
|
3899
|
-
_ts_decorate6([
|
|
3900
|
-
import_async11.synchronized
|
|
3901
|
-
], RtcPeerConnection.prototype, "_openConnection", null);
|
|
3902
|
-
_ts_decorate6([
|
|
3903
|
-
import_async11.synchronized
|
|
3904
|
-
], RtcPeerConnection.prototype, "_lockAndAbort", null);
|
|
3905
|
-
_ts_decorate6([
|
|
3906
|
-
import_async11.synchronized
|
|
3907
|
-
], RtcPeerConnection.prototype, "_lockAndCloseConnection", null);
|
|
3908
|
-
_ts_decorate6([
|
|
3909
|
-
import_async11.synchronized
|
|
3910
|
-
], RtcPeerConnection.prototype, "onSignal", null);
|
|
3911
|
-
_ts_decorate6([
|
|
3912
|
-
import_tracing.trace.info()
|
|
3913
|
-
], RtcPeerConnection.prototype, "_connectionInfo", null);
|
|
3914
|
-
_ts_decorate6([
|
|
3915
|
-
import_log12.logInfo
|
|
3916
|
-
], RtcPeerConnection.prototype, "_loggerContext", null);
|
|
3917
|
-
RtcPeerConnection = _ts_decorate6([
|
|
3918
|
-
import_tracing.trace.resource()
|
|
3919
|
-
], RtcPeerConnection);
|
|
3920
|
-
var isRemoteDescriptionSet = (connection, data) => {
|
|
3921
|
-
if (!connection.remoteDescription?.type || connection.remoteDescription?.type !== data.type) {
|
|
3922
|
-
return false;
|
|
3923
|
-
}
|
|
3924
|
-
return areSdpEqual(connection.remoteDescription.sdp, data.sdp);
|
|
3925
|
-
};
|
|
3926
|
-
var createIceFailureError = (details) => {
|
|
3927
|
-
const candidateErrors = details.map(({ url, errorCode, errorText }) => `${errorCode} ${url}: ${errorText}`);
|
|
3928
|
-
return new import_protocols7.ConnectivityError(`ICE failed:
|
|
3929
|
-
${candidateErrors.join("\n")}`);
|
|
3930
|
-
};
|
|
3931
|
-
var createRtcTransportFactory = (webrtcConfig, iceProvider) => {
|
|
3932
|
-
const connectionFactory = getRtcConnectionFactory();
|
|
3933
|
-
return {
|
|
3934
|
-
createTransport: (options) => {
|
|
3935
|
-
const connection = new RtcPeerConnection(connectionFactory, {
|
|
3936
|
-
ownPeerKey: options.ownPeerKey,
|
|
3937
|
-
remotePeerKey: options.remotePeerKey,
|
|
3938
|
-
sendSignal: options.sendSignal,
|
|
3939
|
-
legacyInitiator: options.initiator,
|
|
3940
|
-
webrtcConfig,
|
|
3941
|
-
iceProvider
|
|
3942
|
-
});
|
|
3943
|
-
return connection.createTransportChannel(options);
|
|
3944
|
-
}
|
|
3945
|
-
};
|
|
3946
|
-
};
|
|
3947
|
-
var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-proxy.ts";
|
|
3948
|
-
var RPC_TIMEOUT = 1e4;
|
|
3949
|
-
var CLOSE_RPC_TIMEOUT = 3e3;
|
|
3950
|
-
var RESP_MIN_THRESHOLD = 500;
|
|
3951
|
-
var RtcTransportProxy = class extends import_context7.Resource {
|
|
3952
|
-
constructor(_options) {
|
|
3953
|
-
super(), this._options = _options, this._proxyId = import_keys10.PublicKey.random(), this.closed = new import_async13.Event(), this.connected = new import_async13.Event(), this.errors = new import_debug6.ErrorStream();
|
|
3954
|
-
}
|
|
3955
|
-
async _open() {
|
|
3956
|
-
let stream;
|
|
3957
|
-
try {
|
|
3958
|
-
stream = this._options.bridgeService.open({
|
|
3959
|
-
proxyId: this._proxyId,
|
|
3960
|
-
remotePeerKey: this._options.remotePeerKey,
|
|
3961
|
-
ownPeerKey: this._options.ownPeerKey,
|
|
3962
|
-
topic: this._options.topic,
|
|
3963
|
-
initiator: this._options.initiator ?? false
|
|
3964
|
-
}, {
|
|
3965
|
-
timeout: RPC_TIMEOUT
|
|
3966
|
-
});
|
|
3967
|
-
} catch (error) {
|
|
3968
|
-
this.errors.raise(error);
|
|
3969
|
-
return;
|
|
3970
|
-
}
|
|
3971
|
-
this._serviceStream = stream;
|
|
3972
|
-
stream.waitUntilReady().then(() => {
|
|
3973
|
-
stream.subscribe(async (event) => {
|
|
3974
|
-
(0, import_log14.log)("rtc transport proxy event", event, {
|
|
3975
|
-
F: __dxlog_file15,
|
|
3976
|
-
L: 66,
|
|
3977
|
-
S: this,
|
|
3978
|
-
C: (f, a) => f(...a)
|
|
3979
|
-
});
|
|
3980
|
-
if (event.connection) {
|
|
3981
|
-
await this._handleConnection(event.connection);
|
|
3982
|
-
} else if (event.data) {
|
|
3983
|
-
this._handleData(event.data);
|
|
3984
|
-
} else if (event.signal) {
|
|
3985
|
-
await this._handleSignal(event.signal);
|
|
3986
|
-
}
|
|
3987
|
-
}, (err) => {
|
|
3988
|
-
(0, import_log14.log)("rtc bridge stream closed", {
|
|
3989
|
-
err
|
|
3990
|
-
}, {
|
|
3991
|
-
F: __dxlog_file15,
|
|
3992
|
-
L: 76,
|
|
3993
|
-
S: this,
|
|
3994
|
-
C: (f, a) => f(...a)
|
|
3995
|
-
});
|
|
3996
|
-
if (err) {
|
|
3997
|
-
this._raiseIfOpen(err);
|
|
3998
|
-
} else {
|
|
3999
|
-
void this.close();
|
|
4000
|
-
}
|
|
4001
|
-
});
|
|
4002
|
-
const connectorStream = new import_node_stream3.Writable({
|
|
4003
|
-
write: (chunk, _, callback) => {
|
|
4004
|
-
const sendStartMs = Date.now();
|
|
4005
|
-
this._options.bridgeService.sendData({
|
|
4006
|
-
proxyId: this._proxyId,
|
|
4007
|
-
payload: chunk
|
|
4008
|
-
}, {
|
|
4009
|
-
timeout: RPC_TIMEOUT
|
|
4010
|
-
}).then(() => {
|
|
4011
|
-
if (Date.now() - sendStartMs > RESP_MIN_THRESHOLD) {
|
|
4012
|
-
(0, import_log14.log)("slow response, delaying callback", void 0, {
|
|
4013
|
-
F: __dxlog_file15,
|
|
4014
|
-
L: 93,
|
|
4015
|
-
S: this,
|
|
4016
|
-
C: (f, a) => f(...a)
|
|
4017
|
-
});
|
|
4018
|
-
(0, import_async13.scheduleTask)(this._ctx, () => callback(), RESP_MIN_THRESHOLD);
|
|
4019
|
-
} else {
|
|
4020
|
-
callback();
|
|
4021
|
-
}
|
|
4022
|
-
}, (err) => {
|
|
4023
|
-
callback();
|
|
4024
|
-
this._raiseIfOpen(err);
|
|
4025
|
-
});
|
|
4026
|
-
}
|
|
4027
|
-
});
|
|
4028
|
-
connectorStream.on("error", (err) => {
|
|
4029
|
-
this._raiseIfOpen(err);
|
|
4030
|
-
});
|
|
4031
|
-
this._options.stream.pipe(connectorStream);
|
|
4032
|
-
}, (error) => {
|
|
4033
|
-
if (error) {
|
|
4034
|
-
this._raiseIfOpen(error);
|
|
4035
|
-
} else {
|
|
4036
|
-
void this.close();
|
|
4037
|
-
}
|
|
4038
|
-
});
|
|
4039
|
-
}
|
|
4040
|
-
async _close() {
|
|
4041
|
-
try {
|
|
4042
|
-
await this._serviceStream?.close();
|
|
4043
|
-
this._serviceStream = void 0;
|
|
4044
|
-
} catch (err) {
|
|
4045
|
-
import_log14.log.catch(err, void 0, {
|
|
4046
|
-
F: __dxlog_file15,
|
|
4047
|
-
L: 128,
|
|
4048
|
-
S: this,
|
|
4049
|
-
C: (f, a) => f(...a)
|
|
4050
|
-
});
|
|
4051
|
-
}
|
|
4052
|
-
try {
|
|
4053
|
-
await this._options.bridgeService.close({
|
|
4054
|
-
proxyId: this._proxyId
|
|
4055
|
-
}, {
|
|
4056
|
-
timeout: CLOSE_RPC_TIMEOUT
|
|
4057
|
-
});
|
|
4058
|
-
} catch (err) {
|
|
4059
|
-
import_log14.log.catch(err, void 0, {
|
|
4060
|
-
F: __dxlog_file15,
|
|
4061
|
-
L: 134,
|
|
4062
|
-
S: this,
|
|
4063
|
-
C: (f, a) => f(...a)
|
|
4064
|
-
});
|
|
4065
|
-
}
|
|
4066
|
-
this.closed.emit();
|
|
4067
|
-
}
|
|
4068
|
-
async onSignal(signal) {
|
|
4069
|
-
this._options.bridgeService.sendSignal({
|
|
4070
|
-
proxyId: this._proxyId,
|
|
4071
|
-
signal
|
|
4072
|
-
}, {
|
|
4073
|
-
timeout: RPC_TIMEOUT
|
|
4074
|
-
}).catch((err) => this._raiseIfOpen(decodeError(err)));
|
|
4075
|
-
}
|
|
4076
|
-
async _handleConnection(connectionEvent) {
|
|
4077
|
-
if (connectionEvent.error) {
|
|
4078
|
-
this.errors.raise(decodeError(connectionEvent.error));
|
|
4079
|
-
return;
|
|
4080
|
-
}
|
|
4081
|
-
switch (connectionEvent.state) {
|
|
4082
|
-
case import_bridge.ConnectionState.CONNECTED: {
|
|
4083
|
-
this.connected.emit();
|
|
4084
|
-
break;
|
|
4085
|
-
}
|
|
4086
|
-
case import_bridge.ConnectionState.CLOSED: {
|
|
4087
|
-
await this.close();
|
|
4088
|
-
break;
|
|
4089
|
-
}
|
|
4090
|
-
}
|
|
4091
|
-
}
|
|
4092
|
-
_handleData(dataEvent) {
|
|
4093
|
-
try {
|
|
4094
|
-
this._options.stream.write((0, import_util9.arrayToBuffer)(dataEvent.payload));
|
|
4095
|
-
} catch (error) {
|
|
4096
|
-
this._raiseIfOpen(error);
|
|
4097
|
-
}
|
|
4098
|
-
}
|
|
4099
|
-
async _handleSignal(signalEvent) {
|
|
4100
|
-
try {
|
|
4101
|
-
await this._options.sendSignal(signalEvent.payload);
|
|
4102
|
-
} catch (error) {
|
|
4103
|
-
const type = signalEvent.payload.payload.data?.type;
|
|
4104
|
-
if (type === "offer" || type === "answer") {
|
|
4105
|
-
this._raiseIfOpen(new import_protocols9.ConnectivityError(`Session establishment failed: ${type} couldn't be sent.`));
|
|
4106
|
-
}
|
|
4107
|
-
}
|
|
4108
|
-
}
|
|
4109
|
-
async getDetails() {
|
|
4110
|
-
try {
|
|
4111
|
-
const response = await this._options.bridgeService.getDetails({
|
|
4112
|
-
proxyId: this._proxyId
|
|
4113
|
-
}, {
|
|
4114
|
-
timeout: RPC_TIMEOUT
|
|
4115
|
-
});
|
|
4116
|
-
return response.details;
|
|
4117
|
-
} catch (err) {
|
|
4118
|
-
return "bridge-svc unreachable";
|
|
4119
|
-
}
|
|
4120
|
-
}
|
|
4121
|
-
async getStats() {
|
|
4122
|
-
try {
|
|
4123
|
-
const response = await this._options.bridgeService.getStats({
|
|
4124
|
-
proxyId: this._proxyId
|
|
4125
|
-
}, {
|
|
4126
|
-
timeout: RPC_TIMEOUT
|
|
4127
|
-
});
|
|
4128
|
-
return response.stats;
|
|
4129
|
-
} catch (err) {
|
|
4130
|
-
return {
|
|
4131
|
-
bytesSent: 0,
|
|
4132
|
-
bytesReceived: 0,
|
|
4133
|
-
packetsSent: 0,
|
|
4134
|
-
packetsReceived: 0,
|
|
4135
|
-
rawStats: "bridge-svc unreachable"
|
|
4136
|
-
};
|
|
4137
|
-
}
|
|
4138
|
-
}
|
|
4139
|
-
_raiseIfOpen(error) {
|
|
4140
|
-
if (this.isOpen) {
|
|
4141
|
-
this.errors.raise(error);
|
|
4142
|
-
} else {
|
|
4143
|
-
import_log14.log.info("error swallowed because transport was closed", {
|
|
4144
|
-
message: error.message
|
|
4145
|
-
}, {
|
|
4146
|
-
F: __dxlog_file15,
|
|
4147
|
-
L: 215,
|
|
4148
|
-
S: this,
|
|
4149
|
-
C: (f, a) => f(...a)
|
|
4150
|
-
});
|
|
4151
|
-
}
|
|
4152
|
-
}
|
|
4153
|
-
/**
|
|
4154
|
-
* Called when underlying proxy service becomes unavailable.
|
|
4155
|
-
*/
|
|
4156
|
-
forceClose() {
|
|
4157
|
-
void this._serviceStream?.close();
|
|
4158
|
-
this.closed.emit();
|
|
4159
|
-
}
|
|
4160
|
-
};
|
|
4161
|
-
var RtcTransportProxyFactory = class {
|
|
4162
|
-
constructor() {
|
|
4163
|
-
this._connections = /* @__PURE__ */ new Set();
|
|
4164
|
-
}
|
|
4165
|
-
/**
|
|
4166
|
-
* Sets the current BridgeService to be used to open connections.
|
|
4167
|
-
* Calling this method will close any existing connections.
|
|
4168
|
-
*/
|
|
4169
|
-
setBridgeService(bridgeService) {
|
|
4170
|
-
this._bridgeService = bridgeService;
|
|
4171
|
-
for (const connection of this._connections) {
|
|
4172
|
-
connection.forceClose();
|
|
4173
|
-
}
|
|
4174
|
-
return this;
|
|
4175
|
-
}
|
|
4176
|
-
createTransport(options) {
|
|
4177
|
-
(0, import_invariant13.invariant)(this._bridgeService, "RtcTransportProxyFactory is not ready to open connections", {
|
|
4178
|
-
F: __dxlog_file15,
|
|
4179
|
-
L: 245,
|
|
4180
|
-
S: this,
|
|
4181
|
-
A: [
|
|
4182
|
-
"this._bridgeService",
|
|
4183
|
-
"'RtcTransportProxyFactory is not ready to open connections'"
|
|
4184
|
-
]
|
|
4185
|
-
});
|
|
4186
|
-
const transport = new RtcTransportProxy({
|
|
4187
|
-
...options,
|
|
4188
|
-
bridgeService: this._bridgeService
|
|
4189
|
-
});
|
|
4190
|
-
this._connections.add(transport);
|
|
4191
|
-
transport.closed.on(() => {
|
|
4192
|
-
this._connections.delete(transport);
|
|
4193
|
-
});
|
|
4194
|
-
return transport;
|
|
4195
|
-
}
|
|
4196
|
-
};
|
|
4197
|
-
var decodeError = (err) => {
|
|
4198
|
-
const message = typeof err === "string" ? err : err.message;
|
|
4199
|
-
if (message.includes("CONNECTION_RESET")) {
|
|
4200
|
-
return new import_protocols9.ConnectionResetError(message);
|
|
4201
|
-
} else if (message.includes("TIMEOUT")) {
|
|
4202
|
-
return new import_protocols9.TimeoutError(message);
|
|
4203
|
-
} else if (message.includes("CONNECTIVITY_ERROR")) {
|
|
4204
|
-
return new import_protocols9.ConnectivityError(message);
|
|
4205
|
-
} else {
|
|
4206
|
-
return typeof err === "string" ? new Error(err) : err;
|
|
4207
|
-
}
|
|
4208
|
-
};
|
|
4209
|
-
var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-service.ts";
|
|
4210
|
-
var RtcTransportService = class {
|
|
4211
|
-
constructor(webrtcConfig, iceProvider, _transportFactory = createRtcTransportFactory(webrtcConfig, iceProvider)) {
|
|
4212
|
-
this._transportFactory = _transportFactory;
|
|
4213
|
-
this._openTransports = new import_util10.ComplexMap(import_keys11.PublicKey.hash);
|
|
4214
|
-
}
|
|
4215
|
-
hasOpenTransports() {
|
|
4216
|
-
return this._openTransports.size > 0;
|
|
4217
|
-
}
|
|
4218
|
-
open(request) {
|
|
4219
|
-
const existingTransport = this._openTransports.get(request.proxyId);
|
|
4220
|
-
if (existingTransport) {
|
|
4221
|
-
import_log15.log.error("requesting a new transport bridge for an existing proxy", void 0, {
|
|
4222
|
-
F: __dxlog_file16,
|
|
4223
|
-
L: 53,
|
|
4224
|
-
S: this,
|
|
4225
|
-
C: (f, a) => f(...a)
|
|
4226
|
-
});
|
|
4227
|
-
void this._safeCloseTransport(existingTransport);
|
|
4228
|
-
this._openTransports.delete(request.proxyId);
|
|
4229
|
-
}
|
|
4230
|
-
return new import_stream.Stream(({ ready, next, close }) => {
|
|
4231
|
-
const pushNewState = createStateUpdater(next);
|
|
4232
|
-
const transportStream = new import_node_stream4.Duplex({
|
|
4233
|
-
read: () => {
|
|
4234
|
-
const callbacks = [
|
|
4235
|
-
...transportState.writeProcessedCallbacks
|
|
4236
|
-
];
|
|
4237
|
-
transportState.writeProcessedCallbacks.length = 0;
|
|
4238
|
-
callbacks.forEach((cb) => cb());
|
|
4239
|
-
},
|
|
4240
|
-
write: function(chunk, _, callback) {
|
|
4241
|
-
next({
|
|
4242
|
-
data: {
|
|
4243
|
-
payload: chunk
|
|
4244
|
-
}
|
|
4245
|
-
});
|
|
4246
|
-
callback();
|
|
4247
|
-
}
|
|
4248
|
-
});
|
|
4249
|
-
const transport = this._transportFactory.createTransport({
|
|
4250
|
-
initiator: request.initiator,
|
|
4251
|
-
topic: request.topic,
|
|
4252
|
-
ownPeerKey: request.ownPeerKey,
|
|
4253
|
-
remotePeerKey: request.remotePeerKey,
|
|
4254
|
-
stream: transportStream,
|
|
4255
|
-
sendSignal: async (signal) => {
|
|
4256
|
-
next({
|
|
4257
|
-
signal: {
|
|
4258
|
-
payload: signal
|
|
4259
|
-
}
|
|
4260
|
-
});
|
|
4261
|
-
}
|
|
4262
|
-
});
|
|
4263
|
-
const transportState = {
|
|
4264
|
-
proxyId: request.proxyId,
|
|
4265
|
-
transport,
|
|
4266
|
-
connectorStream: transportStream,
|
|
4267
|
-
writeProcessedCallbacks: []
|
|
4268
|
-
};
|
|
4269
|
-
transport.connected.on(() => pushNewState(import_bridge2.ConnectionState.CONNECTED));
|
|
4270
|
-
transport.errors.handle(async (err) => {
|
|
4271
|
-
pushNewState(import_bridge2.ConnectionState.CLOSED, err);
|
|
4272
|
-
void this._safeCloseTransport(transportState);
|
|
4273
|
-
close(err);
|
|
4274
|
-
});
|
|
4275
|
-
transport.closed.on(async () => {
|
|
4276
|
-
pushNewState(import_bridge2.ConnectionState.CLOSED);
|
|
4277
|
-
void this._safeCloseTransport(transportState);
|
|
4278
|
-
close();
|
|
4279
|
-
});
|
|
4280
|
-
this._openTransports.set(request.proxyId, transportState);
|
|
4281
|
-
transport.open().catch(async (err) => {
|
|
4282
|
-
pushNewState(import_bridge2.ConnectionState.CLOSED, err);
|
|
4283
|
-
void this._safeCloseTransport(transportState);
|
|
4284
|
-
close(err);
|
|
4285
|
-
});
|
|
4286
|
-
ready();
|
|
4287
|
-
(0, import_log15.log)("stream ready", void 0, {
|
|
4288
|
-
F: __dxlog_file16,
|
|
4289
|
-
L: 115,
|
|
4290
|
-
S: this,
|
|
4291
|
-
C: (f, a) => f(...a)
|
|
4292
|
-
});
|
|
4293
|
-
pushNewState(import_bridge2.ConnectionState.CONNECTING);
|
|
4294
|
-
});
|
|
4295
|
-
}
|
|
4296
|
-
async sendSignal({ proxyId, signal }) {
|
|
4297
|
-
const transport = this._openTransports.get(proxyId);
|
|
4298
|
-
(0, import_invariant14.invariant)(transport, void 0, {
|
|
4299
|
-
F: __dxlog_file16,
|
|
4300
|
-
L: 123,
|
|
4301
|
-
S: this,
|
|
4302
|
-
A: [
|
|
4303
|
-
"transport",
|
|
4304
|
-
""
|
|
4305
|
-
]
|
|
4306
|
-
});
|
|
4307
|
-
await transport.transport.onSignal(signal);
|
|
4308
|
-
}
|
|
4309
|
-
async getDetails({ proxyId }) {
|
|
4310
|
-
const transport = this._openTransports.get(proxyId);
|
|
4311
|
-
(0, import_invariant14.invariant)(transport, void 0, {
|
|
4312
|
-
F: __dxlog_file16,
|
|
4313
|
-
L: 130,
|
|
4314
|
-
S: this,
|
|
4315
|
-
A: [
|
|
4316
|
-
"transport",
|
|
4317
|
-
""
|
|
4318
|
-
]
|
|
4319
|
-
});
|
|
4320
|
-
return {
|
|
4321
|
-
details: await transport.transport.getDetails()
|
|
4322
|
-
};
|
|
4323
|
-
}
|
|
4324
|
-
async getStats({ proxyId }) {
|
|
4325
|
-
const transport = this._openTransports.get(proxyId);
|
|
4326
|
-
(0, import_invariant14.invariant)(transport, void 0, {
|
|
4327
|
-
F: __dxlog_file16,
|
|
4328
|
-
L: 137,
|
|
4329
|
-
S: this,
|
|
4330
|
-
A: [
|
|
4331
|
-
"transport",
|
|
4332
|
-
""
|
|
4333
|
-
]
|
|
4334
|
-
});
|
|
4335
|
-
return {
|
|
4336
|
-
stats: await transport.transport.getStats()
|
|
4337
|
-
};
|
|
4338
|
-
}
|
|
4339
|
-
async sendData({ proxyId, payload }) {
|
|
4340
|
-
const transport = this._openTransports.get(proxyId);
|
|
4341
|
-
(0, import_invariant14.invariant)(transport, void 0, {
|
|
4342
|
-
F: __dxlog_file16,
|
|
4343
|
-
L: 144,
|
|
4344
|
-
S: this,
|
|
4345
|
-
A: [
|
|
4346
|
-
"transport",
|
|
4347
|
-
""
|
|
4348
|
-
]
|
|
4349
|
-
});
|
|
4350
|
-
const bufferHasSpace = transport.connectorStream.push(payload);
|
|
4351
|
-
if (!bufferHasSpace) {
|
|
4352
|
-
await new Promise((resolve) => {
|
|
4353
|
-
transport.writeProcessedCallbacks.push(resolve);
|
|
4354
|
-
});
|
|
4355
|
-
}
|
|
4356
|
-
}
|
|
4357
|
-
async close({ proxyId }) {
|
|
4358
|
-
const transport = this._openTransports.get(proxyId);
|
|
4359
|
-
if (!transport) {
|
|
4360
|
-
return;
|
|
4361
|
-
}
|
|
4362
|
-
this._openTransports.delete(proxyId);
|
|
4363
|
-
await this._safeCloseTransport(transport);
|
|
4364
|
-
}
|
|
4365
|
-
async _safeCloseTransport(transport) {
|
|
4366
|
-
if (this._openTransports.get(transport.proxyId) === transport) {
|
|
4367
|
-
this._openTransports.delete(transport.proxyId);
|
|
4368
|
-
}
|
|
4369
|
-
transport.writeProcessedCallbacks.forEach((cb) => cb());
|
|
4370
|
-
try {
|
|
4371
|
-
await transport.transport.close();
|
|
4372
|
-
} catch (error) {
|
|
4373
|
-
import_log15.log.warn("transport close error", {
|
|
4374
|
-
message: error?.message
|
|
4375
|
-
}, {
|
|
4376
|
-
F: __dxlog_file16,
|
|
4377
|
-
L: 174,
|
|
4378
|
-
S: this,
|
|
4379
|
-
C: (f, a) => f(...a)
|
|
4380
|
-
});
|
|
4381
|
-
}
|
|
4382
|
-
try {
|
|
4383
|
-
transport.connectorStream.end();
|
|
4384
|
-
} catch (error) {
|
|
4385
|
-
import_log15.log.warn("connectorStream close error", {
|
|
4386
|
-
message: error?.message
|
|
4387
|
-
}, {
|
|
4388
|
-
F: __dxlog_file16,
|
|
4389
|
-
L: 179,
|
|
4390
|
-
S: this,
|
|
4391
|
-
C: (f, a) => f(...a)
|
|
4392
|
-
});
|
|
4393
|
-
}
|
|
4394
|
-
(0, import_log15.log)("closed", void 0, {
|
|
4395
|
-
F: __dxlog_file16,
|
|
4396
|
-
L: 181,
|
|
4397
|
-
S: this,
|
|
4398
|
-
C: (f, a) => f(...a)
|
|
4399
|
-
});
|
|
4400
|
-
}
|
|
4401
|
-
};
|
|
4402
|
-
var createStateUpdater = (next) => {
|
|
4403
|
-
return (state, err) => {
|
|
4404
|
-
next({
|
|
4405
|
-
connection: {
|
|
4406
|
-
state,
|
|
4407
|
-
...err ? {
|
|
4408
|
-
error: err.message
|
|
4409
|
-
} : void 0
|
|
4410
|
-
}
|
|
4411
|
-
});
|
|
4412
|
-
};
|
|
4413
|
-
};
|
|
4414
|
-
var createTeleportProtocolFactory = (onConnection, defaultParams) => {
|
|
4415
|
-
return (params) => {
|
|
4416
|
-
const teleport = new import_teleport.Teleport({
|
|
4417
|
-
...defaultParams,
|
|
4418
|
-
...params
|
|
4419
|
-
});
|
|
4420
|
-
return {
|
|
4421
|
-
stream: teleport.stream,
|
|
4422
|
-
open: async (sessionId) => {
|
|
4423
|
-
await teleport.open(sessionId);
|
|
4424
|
-
await onConnection(teleport);
|
|
4425
|
-
},
|
|
4426
|
-
close: async () => {
|
|
4427
|
-
await teleport.close();
|
|
4428
|
-
},
|
|
4429
|
-
abort: async () => {
|
|
4430
|
-
await teleport.abort();
|
|
4431
|
-
}
|
|
4432
|
-
};
|
|
4433
|
-
};
|
|
4434
|
-
};
|
|
4435
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
4436
|
-
0 && (module.exports = {
|
|
4437
|
-
Connection,
|
|
4438
|
-
ConnectionLimiter,
|
|
4439
|
-
ConnectionLog,
|
|
4440
|
-
ConnectionState,
|
|
4441
|
-
EventType,
|
|
4442
|
-
FullyConnectedTopology,
|
|
4443
|
-
MAX_CONCURRENT_INITIATING_CONNECTIONS,
|
|
4444
|
-
MMSTTopology,
|
|
4445
|
-
MemoryTransport,
|
|
4446
|
-
MemoryTransportFactory,
|
|
4447
|
-
RtcTransportProxy,
|
|
4448
|
-
RtcTransportProxyFactory,
|
|
4449
|
-
RtcTransportService,
|
|
4450
|
-
StarTopology,
|
|
4451
|
-
Swarm,
|
|
4452
|
-
SwarmMapper,
|
|
4453
|
-
SwarmMessenger,
|
|
4454
|
-
SwarmNetworkManager,
|
|
4455
|
-
TransportKind,
|
|
4456
|
-
createIceProvider,
|
|
4457
|
-
createRtcTransportFactory,
|
|
4458
|
-
createTeleportProtocolFactory
|
|
4459
|
-
});
|
|
4460
|
-
//# sourceMappingURL=chunk-2G6RZMS5.cjs.map
|