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