@streamr/dht 103.3.1 → 103.6.0-rc.0
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/exports-browser.cjs +548 -100
- package/dist/exports-browser.cjs.map +1 -1
- package/dist/exports-browser.d.ts +6 -4
- package/dist/exports-browser.js +529 -101
- package/dist/exports-browser.js.map +1 -1
- package/dist/exports-nodejs.cjs +9 -1
- package/dist/exports-nodejs.cjs.map +1 -1
- package/dist/exports-nodejs.d.ts +9 -4
- package/dist/exports-nodejs.js +9 -2
- package/dist/exports-nodejs.js.map +1 -1
- package/package.json +12 -8
package/dist/exports-browser.js
CHANGED
|
@@ -9,6 +9,7 @@ import { ServiceType, stackIntercept } from '@protobuf-ts/runtime-rpc';
|
|
|
9
9
|
import { v4 } from 'uuid';
|
|
10
10
|
import { ProtoCallContext, RpcCommunicator, toProtoRpcClient, protoClasses as protoClasses$1, RpcError } from '@streamr/proto-rpc';
|
|
11
11
|
import ipaddr from 'ipaddr.js';
|
|
12
|
+
import * as Comlink from 'comlink';
|
|
12
13
|
import { w3cwebsocket } from 'websocket';
|
|
13
14
|
import { SERVICE_ID } from '@streamr/autocertifier-client';
|
|
14
15
|
import shuffle from 'lodash/shuffle';
|
|
@@ -1798,7 +1799,7 @@ const createRandomConnectionId = () => {
|
|
|
1798
1799
|
return v4();
|
|
1799
1800
|
};
|
|
1800
1801
|
|
|
1801
|
-
const logger$
|
|
1802
|
+
const logger$D = new Logger('ManagedConnection');
|
|
1802
1803
|
// ManagedConnection is a component used as a wrapper for IConnection after they have been successfully handshaked.
|
|
1803
1804
|
// Should only be used in the ConnectionManager.
|
|
1804
1805
|
class ManagedConnection extends EventEmitter {
|
|
@@ -1828,7 +1829,7 @@ class ManagedConnection extends EventEmitter {
|
|
|
1828
1829
|
this.remotePeerDescriptor = peerDescriptor;
|
|
1829
1830
|
}
|
|
1830
1831
|
onDisconnected(gracefulLeave) {
|
|
1831
|
-
logger$
|
|
1832
|
+
logger$D.trace(getNodeIdOrUnknownFromPeerDescriptor(this.remotePeerDescriptor) + ' onDisconnected() ' + gracefulLeave);
|
|
1832
1833
|
if (!this.replacedAsDuplicate) {
|
|
1833
1834
|
this.emit('disconnected', gracefulLeave);
|
|
1834
1835
|
}
|
|
@@ -1837,7 +1838,7 @@ class ManagedConnection extends EventEmitter {
|
|
|
1837
1838
|
// TODO: Can this be removed if ManagedConnections can never be duplicates?
|
|
1838
1839
|
// Handle duplicates in the ConncetorFacade and no longer have PendingConnections in ConnectionManager
|
|
1839
1840
|
replaceAsDuplicate() {
|
|
1840
|
-
logger$
|
|
1841
|
+
logger$D.trace(getNodeIdOrUnknownFromPeerDescriptor(this.remotePeerDescriptor) + ' replaceAsDuplicate');
|
|
1841
1842
|
this.replacedAsDuplicate = true;
|
|
1842
1843
|
}
|
|
1843
1844
|
send(data) {
|
|
@@ -1984,10 +1985,10 @@ class RpcRemote {
|
|
|
1984
1985
|
}
|
|
1985
1986
|
}
|
|
1986
1987
|
|
|
1987
|
-
const logger$
|
|
1988
|
+
const logger$C = new Logger('ConnectionLockRpcRemote');
|
|
1988
1989
|
class ConnectionLockRpcRemote extends RpcRemote {
|
|
1989
1990
|
async lockRequest(lockId) {
|
|
1990
|
-
logger$
|
|
1991
|
+
logger$C.trace(`Requesting locked connection to ${toNodeId(this.getPeerDescriptor())}`);
|
|
1991
1992
|
const request = {
|
|
1992
1993
|
lockId
|
|
1993
1994
|
};
|
|
@@ -1997,12 +1998,12 @@ class ConnectionLockRpcRemote extends RpcRemote {
|
|
|
1997
1998
|
return res.accepted;
|
|
1998
1999
|
}
|
|
1999
2000
|
catch (err) {
|
|
2000
|
-
logger$
|
|
2001
|
+
logger$C.debug('Connection lock rejected', { err });
|
|
2001
2002
|
return false;
|
|
2002
2003
|
}
|
|
2003
2004
|
}
|
|
2004
2005
|
unlockRequest(lockId) {
|
|
2005
|
-
logger$
|
|
2006
|
+
logger$C.trace(`Requesting connection to be unlocked from ${toNodeId(this.getPeerDescriptor())}`);
|
|
2006
2007
|
const request = {
|
|
2007
2008
|
lockId
|
|
2008
2009
|
};
|
|
@@ -2010,11 +2011,11 @@ class ConnectionLockRpcRemote extends RpcRemote {
|
|
|
2010
2011
|
notification: true
|
|
2011
2012
|
});
|
|
2012
2013
|
this.getClient().unlockRequest(request, options).catch((_e) => {
|
|
2013
|
-
logger$
|
|
2014
|
+
logger$C.trace('failed to send unlockRequest');
|
|
2014
2015
|
});
|
|
2015
2016
|
}
|
|
2016
2017
|
async gracefulDisconnect(disconnectMode) {
|
|
2017
|
-
logger$
|
|
2018
|
+
logger$C.trace(`Notifying a graceful disconnect to ${toNodeId(this.getPeerDescriptor())}`);
|
|
2018
2019
|
const request = {
|
|
2019
2020
|
disconnectMode
|
|
2020
2021
|
};
|
|
@@ -2026,7 +2027,7 @@ class ConnectionLockRpcRemote extends RpcRemote {
|
|
|
2026
2027
|
await this.getClient().gracefulDisconnect(request, options);
|
|
2027
2028
|
}
|
|
2028
2029
|
async setPrivate(isPrivate) {
|
|
2029
|
-
logger$
|
|
2030
|
+
logger$C.trace(`Setting isPrivate: ${isPrivate} for ${toNodeId(this.getPeerDescriptor())}`);
|
|
2030
2031
|
const request = {
|
|
2031
2032
|
isPrivate
|
|
2032
2033
|
};
|
|
@@ -2038,7 +2039,7 @@ class ConnectionLockRpcRemote extends RpcRemote {
|
|
|
2038
2039
|
}
|
|
2039
2040
|
}
|
|
2040
2041
|
|
|
2041
|
-
const logger$
|
|
2042
|
+
const logger$B = new Logger('ConnectionLockRpcLocal');
|
|
2042
2043
|
class ConnectionLockRpcLocal {
|
|
2043
2044
|
options;
|
|
2044
2045
|
constructor(options) {
|
|
@@ -2067,7 +2068,7 @@ class ConnectionLockRpcLocal {
|
|
|
2067
2068
|
}
|
|
2068
2069
|
async gracefulDisconnect(disconnectNotice, context) {
|
|
2069
2070
|
const senderPeerDescriptor = context.incomingSourceDescriptor;
|
|
2070
|
-
logger$
|
|
2071
|
+
logger$B.trace(getNodeIdOrUnknownFromPeerDescriptor(senderPeerDescriptor) + ' received gracefulDisconnect notice');
|
|
2071
2072
|
if (disconnectNotice.disconnectMode === DisconnectMode.LEAVING) {
|
|
2072
2073
|
await this.options.closeConnection(senderPeerDescriptor, true, 'graceful leave notified');
|
|
2073
2074
|
}
|
|
@@ -2118,7 +2119,7 @@ var NatType;
|
|
|
2118
2119
|
NatType["OPEN_INTERNET"] = "open_internet";
|
|
2119
2120
|
NatType["UNKNOWN"] = "unknown";
|
|
2120
2121
|
})(NatType || (NatType = {}));
|
|
2121
|
-
const logger$
|
|
2122
|
+
const logger$A = new Logger('ConnectionManager');
|
|
2122
2123
|
var ConnectionManagerState;
|
|
2123
2124
|
(function (ConnectionManagerState) {
|
|
2124
2125
|
ConnectionManagerState["IDLE"] = "idle";
|
|
@@ -2168,7 +2169,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2168
2169
|
getLocalPeerDescriptor: () => this.getLocalPeerDescriptor(),
|
|
2169
2170
|
setPrivate: (id, isPrivate) => {
|
|
2170
2171
|
if (!this.options.allowIncomingPrivateConnections) {
|
|
2171
|
-
logger$
|
|
2172
|
+
logger$A.debug(`node ${id} attemted to set a connection as private, but it is not allowed`);
|
|
2172
2173
|
return;
|
|
2173
2174
|
}
|
|
2174
2175
|
if (isPrivate) {
|
|
@@ -2202,7 +2203,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2202
2203
|
const connection = endpoint.connection;
|
|
2203
2204
|
const nodeId = connection.getNodeId();
|
|
2204
2205
|
if (!this.locks.isLocked(nodeId) && !this.locks.isPrivate(nodeId) && Date.now() - connection.getLastUsedTimestamp() > maxIdleTime) {
|
|
2205
|
-
logger$
|
|
2206
|
+
logger$A.trace('disconnecting in timeout interval: ' + getNodeIdOrUnknownFromPeerDescriptor(connection.getPeerDescriptor()));
|
|
2206
2207
|
disconnectionCandidates.addContact(connection);
|
|
2207
2208
|
}
|
|
2208
2209
|
}
|
|
@@ -2210,7 +2211,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2210
2211
|
const disconnectables = disconnectionCandidates.getFurthestContacts(this.endpoints.size - maxConnections);
|
|
2211
2212
|
for (const disconnectable of disconnectables) {
|
|
2212
2213
|
const peerDescriptor = disconnectable.getPeerDescriptor();
|
|
2213
|
-
logger$
|
|
2214
|
+
logger$A.trace('garbageCollecting ' + toNodeId(peerDescriptor));
|
|
2214
2215
|
this.gracefullyDisconnectAsync(peerDescriptor, DisconnectMode.NORMAL).catch((_e) => { });
|
|
2215
2216
|
}
|
|
2216
2217
|
}
|
|
@@ -2219,11 +2220,11 @@ class ConnectionManager extends EventEmitter {
|
|
|
2219
2220
|
throw new CouldNotStart(`Cannot start already ${this.state} module`);
|
|
2220
2221
|
}
|
|
2221
2222
|
this.state = ConnectionManagerState.RUNNING;
|
|
2222
|
-
logger$
|
|
2223
|
+
logger$A.trace(`Starting ConnectionManager...`);
|
|
2223
2224
|
await this.connectorFacade.start((connection) => this.onNewConnection(connection), (nodeId) => this.hasConnection(nodeId), this);
|
|
2224
2225
|
// Garbage collection of connections
|
|
2225
2226
|
this.disconnectorIntervalRef = setInterval(() => {
|
|
2226
|
-
logger$
|
|
2227
|
+
logger$A.trace('disconnectorInterval');
|
|
2227
2228
|
const LAST_USED_LIMIT = 20000;
|
|
2228
2229
|
this.garbageCollectConnections(this.options.maxConnections ?? 80, LAST_USED_LIMIT);
|
|
2229
2230
|
}, 5000); // TODO use options option or named constant?
|
|
@@ -2233,7 +2234,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2233
2234
|
return;
|
|
2234
2235
|
}
|
|
2235
2236
|
this.state = ConnectionManagerState.STOPPING;
|
|
2236
|
-
logger$
|
|
2237
|
+
logger$A.trace(`Stopping ConnectionManager`);
|
|
2237
2238
|
if (this.disconnectorIntervalRef) {
|
|
2238
2239
|
clearInterval(this.disconnectorIntervalRef);
|
|
2239
2240
|
}
|
|
@@ -2243,23 +2244,23 @@ class ConnectionManager extends EventEmitter {
|
|
|
2243
2244
|
await this.gracefullyDisconnectAsync(endpoint.connection.getPeerDescriptor(), DisconnectMode.LEAVING);
|
|
2244
2245
|
}
|
|
2245
2246
|
catch (e) {
|
|
2246
|
-
logger$
|
|
2247
|
+
logger$A.error(e);
|
|
2247
2248
|
}
|
|
2248
2249
|
}
|
|
2249
2250
|
else {
|
|
2250
2251
|
const connection = endpoint.connection;
|
|
2251
|
-
logger$
|
|
2252
|
+
logger$A.trace('handshake of connection not completed, force-closing');
|
|
2252
2253
|
// TODO use options option or named constant?
|
|
2253
2254
|
const eventReceived = waitForEvent(connection, 'disconnected', 2000);
|
|
2254
2255
|
// TODO should we have some handling for this floating promise?
|
|
2255
2256
|
connection.close(true);
|
|
2256
2257
|
try {
|
|
2257
2258
|
await eventReceived;
|
|
2258
|
-
logger$
|
|
2259
|
+
logger$A.trace('resolving after receiving disconnected event from non-handshaked connection');
|
|
2259
2260
|
}
|
|
2260
2261
|
catch (e) {
|
|
2261
2262
|
endpoint.buffer.reject();
|
|
2262
|
-
logger$
|
|
2263
|
+
logger$A.trace('force-closing non-handshaked connection timed out ' + e);
|
|
2263
2264
|
}
|
|
2264
2265
|
}
|
|
2265
2266
|
}));
|
|
@@ -2288,7 +2289,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2288
2289
|
throw new CannotConnectToSelf('Cannot send to self');
|
|
2289
2290
|
}
|
|
2290
2291
|
const nodeId = toNodeId(peerDescriptor);
|
|
2291
|
-
logger$
|
|
2292
|
+
logger$A.trace(`Sending message to: ${nodeId}`);
|
|
2292
2293
|
message = {
|
|
2293
2294
|
...message,
|
|
2294
2295
|
sourceDescriptor: this.getLocalPeerDescriptor()
|
|
@@ -2343,13 +2344,13 @@ class ConnectionManager extends EventEmitter {
|
|
|
2343
2344
|
}
|
|
2344
2345
|
handleMessage(message) {
|
|
2345
2346
|
const messageType = message.body.oneofKind;
|
|
2346
|
-
logger$
|
|
2347
|
+
logger$A.trace('Received message of type ' + messageType);
|
|
2347
2348
|
if (messageType !== 'rpcMessage') {
|
|
2348
|
-
logger$
|
|
2349
|
+
logger$A.trace('Filtered out non-RPC message of type ' + messageType);
|
|
2349
2350
|
return;
|
|
2350
2351
|
}
|
|
2351
2352
|
if (this.duplicateMessageDetector.isMostLikelyDuplicate(message.messageId)) {
|
|
2352
|
-
logger$
|
|
2353
|
+
logger$A.trace('handleMessage filtered duplicate ' + toNodeId(message.sourceDescriptor)
|
|
2353
2354
|
+ ' ' + message.serviceId + ' ' + message.messageId);
|
|
2354
2355
|
return;
|
|
2355
2356
|
}
|
|
@@ -2358,7 +2359,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2358
2359
|
this.rpcCommunicator?.handleMessageFromPeer(message);
|
|
2359
2360
|
}
|
|
2360
2361
|
else {
|
|
2361
|
-
logger$
|
|
2362
|
+
logger$A.trace('emit "message" ' + toNodeId(message.sourceDescriptor)
|
|
2362
2363
|
+ ' ' + message.serviceId + ' ' + message.messageId);
|
|
2363
2364
|
this.emit('message', message);
|
|
2364
2365
|
}
|
|
@@ -2375,7 +2376,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2375
2376
|
}
|
|
2376
2377
|
catch (e) {
|
|
2377
2378
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
2378
|
-
logger$
|
|
2379
|
+
logger$A.debug(`Parsing incoming data into Message failed: ${e}`);
|
|
2379
2380
|
return;
|
|
2380
2381
|
}
|
|
2381
2382
|
message.sourceDescriptor = peerDescriptor;
|
|
@@ -2384,7 +2385,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2384
2385
|
}
|
|
2385
2386
|
catch (e) {
|
|
2386
2387
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
2387
|
-
logger$
|
|
2388
|
+
logger$A.debug(`Handling incoming data failed: ${e}`);
|
|
2388
2389
|
}
|
|
2389
2390
|
}
|
|
2390
2391
|
onConnected(peerDescriptor, connection) {
|
|
@@ -2397,7 +2398,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2397
2398
|
const pendingConnection = endpoint.connection;
|
|
2398
2399
|
const buffer = outputBuffer.getBuffer();
|
|
2399
2400
|
while (buffer.length > 0) {
|
|
2400
|
-
logger$
|
|
2401
|
+
logger$A.trace('emptying buffer');
|
|
2401
2402
|
managedConnection.send(buffer.shift());
|
|
2402
2403
|
}
|
|
2403
2404
|
outputBuffer.resolve();
|
|
@@ -2414,7 +2415,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2414
2415
|
}
|
|
2415
2416
|
onDisconnected(peerDescriptor, gracefulLeave) {
|
|
2416
2417
|
const nodeId = toNodeId(peerDescriptor);
|
|
2417
|
-
logger$
|
|
2418
|
+
logger$A.trace(nodeId + ' onDisconnected() gracefulLeave: ' + gracefulLeave);
|
|
2418
2419
|
const endpoint = this.endpoints.get(nodeId);
|
|
2419
2420
|
if (endpoint) {
|
|
2420
2421
|
this.locks.clearAllLocks(nodeId);
|
|
@@ -2422,7 +2423,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2422
2423
|
endpoint.buffer.reject();
|
|
2423
2424
|
}
|
|
2424
2425
|
this.endpoints.delete(nodeId);
|
|
2425
|
-
logger$
|
|
2426
|
+
logger$A.trace(nodeId + ' deleted connection in onDisconnected() gracefulLeave: ' + gracefulLeave);
|
|
2426
2427
|
this.emit('disconnected', peerDescriptor, gracefulLeave);
|
|
2427
2428
|
this.onConnectionCountChange();
|
|
2428
2429
|
}
|
|
@@ -2431,7 +2432,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2431
2432
|
if (this.state === ConnectionManagerState.STOPPED) {
|
|
2432
2433
|
return false;
|
|
2433
2434
|
}
|
|
2434
|
-
logger$
|
|
2435
|
+
logger$A.trace('onNewConnection()');
|
|
2435
2436
|
if (!this.acceptNewConnection(connection)) {
|
|
2436
2437
|
return false;
|
|
2437
2438
|
}
|
|
@@ -2441,7 +2442,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2441
2442
|
}
|
|
2442
2443
|
acceptNewConnection(newConnection) {
|
|
2443
2444
|
const nodeId = toNodeId(newConnection.getPeerDescriptor());
|
|
2444
|
-
logger$
|
|
2445
|
+
logger$A.trace(nodeId + ' acceptNewConnection()');
|
|
2445
2446
|
if (this.endpoints.has(nodeId)) {
|
|
2446
2447
|
if (getOfferer(toNodeId(this.getLocalPeerDescriptor()), nodeId) === 'remote') {
|
|
2447
2448
|
let buffer;
|
|
@@ -2450,14 +2451,14 @@ class ConnectionManager extends EventEmitter {
|
|
|
2450
2451
|
// Could be related to WS client connections not realizing that they have been disconnected.
|
|
2451
2452
|
// Makes refactoring duplicate connection handling to the connectors very difficult.
|
|
2452
2453
|
if (this.endpoints.get(nodeId).connected) {
|
|
2453
|
-
logger$
|
|
2454
|
+
logger$A.debug('replacing connected connection', { nodeId });
|
|
2454
2455
|
buffer = new OutputBuffer();
|
|
2455
2456
|
}
|
|
2456
2457
|
else {
|
|
2457
2458
|
buffer = endpoint.buffer;
|
|
2458
2459
|
}
|
|
2459
2460
|
const oldConnection = endpoint.connection;
|
|
2460
|
-
logger$
|
|
2461
|
+
logger$A.trace('replaced: ' + nodeId);
|
|
2461
2462
|
oldConnection.replaceAsDuplicate();
|
|
2462
2463
|
this.endpoints.set(nodeId, { connected: false, connection: newConnection, buffer: buffer });
|
|
2463
2464
|
return true;
|
|
@@ -2466,7 +2467,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2466
2467
|
return false;
|
|
2467
2468
|
}
|
|
2468
2469
|
}
|
|
2469
|
-
logger$
|
|
2470
|
+
logger$A.trace(nodeId + ' added to connections at acceptNewConnection');
|
|
2470
2471
|
this.endpoints.set(nodeId, {
|
|
2471
2472
|
connected: false,
|
|
2472
2473
|
buffer: new OutputBuffer(),
|
|
@@ -2476,14 +2477,14 @@ class ConnectionManager extends EventEmitter {
|
|
|
2476
2477
|
}
|
|
2477
2478
|
async closeConnection(peerDescriptor, gracefulLeave, reason) {
|
|
2478
2479
|
const nodeId = toNodeId(peerDescriptor);
|
|
2479
|
-
logger$
|
|
2480
|
+
logger$A.trace(nodeId + ' ' + 'closeConnection() ' + reason);
|
|
2480
2481
|
this.locks.clearAllLocks(nodeId);
|
|
2481
2482
|
if (this.endpoints.has(nodeId)) {
|
|
2482
2483
|
const connectionToClose = this.endpoints.get(nodeId).connection;
|
|
2483
2484
|
await connectionToClose.close(gracefulLeave);
|
|
2484
2485
|
}
|
|
2485
2486
|
else {
|
|
2486
|
-
logger$
|
|
2487
|
+
logger$A.trace(nodeId + ' ' + 'closeConnection() this.endpoints did not have the id');
|
|
2487
2488
|
this.emit('disconnected', peerDescriptor, false);
|
|
2488
2489
|
}
|
|
2489
2490
|
}
|
|
@@ -2495,8 +2496,8 @@ class ConnectionManager extends EventEmitter {
|
|
|
2495
2496
|
const rpcRemote = new ConnectionLockRpcRemote(this.getLocalPeerDescriptor(), targetDescriptor, this.rpcCommunicator, ConnectionLockRpcClient);
|
|
2496
2497
|
this.locks.addLocalLocked(nodeId, lockId);
|
|
2497
2498
|
rpcRemote.lockRequest(lockId)
|
|
2498
|
-
.then((_accepted) => logger$
|
|
2499
|
-
.catch((err) => { logger$
|
|
2499
|
+
.then((_accepted) => logger$A.trace('LockRequest successful'))
|
|
2500
|
+
.catch((err) => { logger$A.debug(err); });
|
|
2500
2501
|
}
|
|
2501
2502
|
unlockConnection(targetDescriptor, lockId) {
|
|
2502
2503
|
if (this.state === ConnectionManagerState.STOPPED || areEqualPeerDescriptors(targetDescriptor, this.getLocalPeerDescriptor())) {
|
|
@@ -2548,7 +2549,7 @@ class ConnectionManager extends EventEmitter {
|
|
|
2548
2549
|
async gracefullyDisconnectAsync(targetDescriptor, disconnectMode) {
|
|
2549
2550
|
const endpoint = this.endpoints.get(toNodeId(targetDescriptor));
|
|
2550
2551
|
if (!endpoint) {
|
|
2551
|
-
logger$
|
|
2552
|
+
logger$A.debug('gracefullyDisconnectedAsync() tried on a non-existing connection');
|
|
2552
2553
|
return;
|
|
2553
2554
|
}
|
|
2554
2555
|
if (endpoint.connected) {
|
|
@@ -2557,15 +2558,15 @@ class ConnectionManager extends EventEmitter {
|
|
|
2557
2558
|
// TODO use options option or named constant?
|
|
2558
2559
|
// eslint-disable-next-line promise/catch-or-return
|
|
2559
2560
|
waitForEvent(connection, 'disconnected', 2000).then(() => {
|
|
2560
|
-
logger$
|
|
2561
|
+
logger$A.trace('disconnected event received in gracefullyDisconnectAsync()');
|
|
2561
2562
|
})
|
|
2562
2563
|
.catch((e) => {
|
|
2563
|
-
logger$
|
|
2564
|
+
logger$A.trace('force-closing connection after timeout ' + e);
|
|
2564
2565
|
// TODO should we have some handling for this floating promise?
|
|
2565
2566
|
connection.close(true);
|
|
2566
2567
|
})
|
|
2567
2568
|
.finally(() => {
|
|
2568
|
-
logger$
|
|
2569
|
+
logger$A.trace('resolving after receiving disconnected event');
|
|
2569
2570
|
resolve();
|
|
2570
2571
|
});
|
|
2571
2572
|
});
|
|
@@ -2580,13 +2581,13 @@ class ConnectionManager extends EventEmitter {
|
|
|
2580
2581
|
}
|
|
2581
2582
|
async doGracefullyDisconnectAsync(targetDescriptor, disconnectMode) {
|
|
2582
2583
|
const nodeId = toNodeId(targetDescriptor);
|
|
2583
|
-
logger$
|
|
2584
|
+
logger$A.trace(nodeId + ' gracefullyDisconnectAsync()');
|
|
2584
2585
|
const rpcRemote = new ConnectionLockRpcRemote(this.getLocalPeerDescriptor(), targetDescriptor, this.rpcCommunicator, ConnectionLockRpcClient);
|
|
2585
2586
|
try {
|
|
2586
2587
|
await rpcRemote.gracefulDisconnect(disconnectMode);
|
|
2587
2588
|
}
|
|
2588
2589
|
catch (ex) {
|
|
2589
|
-
logger$
|
|
2590
|
+
logger$A.trace(nodeId + ' remote.gracefulDisconnect() failed' + ex);
|
|
2590
2591
|
}
|
|
2591
2592
|
}
|
|
2592
2593
|
getConnections() {
|
|
@@ -2653,7 +2654,7 @@ function protoToString(protoObj, objectType) {
|
|
|
2653
2654
|
return ret;
|
|
2654
2655
|
}
|
|
2655
2656
|
|
|
2656
|
-
const logger$
|
|
2657
|
+
const logger$z = new Logger('SimulatorConnection');
|
|
2657
2658
|
class SimulatorConnection extends Connection {
|
|
2658
2659
|
stopped = false;
|
|
2659
2660
|
localPeerDescriptor;
|
|
@@ -2675,46 +2676,46 @@ class SimulatorConnection extends Connection {
|
|
|
2675
2676
|
this.doDisconnect = this.doDisconnect.bind(this);
|
|
2676
2677
|
}
|
|
2677
2678
|
send(data) {
|
|
2678
|
-
logger$
|
|
2679
|
+
logger$z.trace('send()');
|
|
2679
2680
|
if (!this.stopped) {
|
|
2680
2681
|
this.simulator.send(this, data);
|
|
2681
2682
|
}
|
|
2682
2683
|
else {
|
|
2683
2684
|
const localNodeId = toNodeId(this.localPeerDescriptor);
|
|
2684
2685
|
const targetNodeId = toNodeId(this.targetPeerDescriptor);
|
|
2685
|
-
logger$
|
|
2686
|
+
logger$z.error(localNodeId + ', ' + targetNodeId + 'tried to send() on a stopped connection');
|
|
2686
2687
|
}
|
|
2687
2688
|
}
|
|
2688
2689
|
async close(gracefulLeave) {
|
|
2689
2690
|
const localNodeId = toNodeId(this.localPeerDescriptor);
|
|
2690
2691
|
const targetNodeId = toNodeId(this.targetPeerDescriptor);
|
|
2691
|
-
logger$
|
|
2692
|
+
logger$z.trace(localNodeId + ', ' + targetNodeId + ' close()');
|
|
2692
2693
|
if (!this.stopped) {
|
|
2693
|
-
logger$
|
|
2694
|
+
logger$z.trace(localNodeId + ', ' + targetNodeId + ' close() not stopped');
|
|
2694
2695
|
this.stopped = true;
|
|
2695
2696
|
try {
|
|
2696
|
-
logger$
|
|
2697
|
+
logger$z.trace(localNodeId + ', ' + targetNodeId + ' close() calling simulator.disconnect()');
|
|
2697
2698
|
this.simulator.close(this);
|
|
2698
|
-
logger$
|
|
2699
|
+
logger$z.trace(localNodeId + ', ' + targetNodeId + ' close() simulator.disconnect returned');
|
|
2699
2700
|
}
|
|
2700
2701
|
catch (e) {
|
|
2701
|
-
logger$
|
|
2702
|
+
logger$z.trace(localNodeId + ', ' + targetNodeId + 'close aborted' + e);
|
|
2702
2703
|
}
|
|
2703
2704
|
finally {
|
|
2704
|
-
logger$
|
|
2705
|
+
logger$z.trace(localNodeId + ', ' + targetNodeId + ' calling this.doDisconnect');
|
|
2705
2706
|
this.doDisconnect(gracefulLeave);
|
|
2706
2707
|
}
|
|
2707
2708
|
}
|
|
2708
2709
|
else {
|
|
2709
|
-
logger$
|
|
2710
|
+
logger$z.trace(localNodeId + ', ' + targetNodeId + ' close() tried to close a stopped connection');
|
|
2710
2711
|
}
|
|
2711
2712
|
}
|
|
2712
2713
|
connect() {
|
|
2713
2714
|
if (!this.stopped) {
|
|
2714
|
-
logger$
|
|
2715
|
+
logger$z.trace('connect() called');
|
|
2715
2716
|
this.simulator.connect(this, this.targetPeerDescriptor, (error) => {
|
|
2716
2717
|
if (error !== undefined) {
|
|
2717
|
-
logger$
|
|
2718
|
+
logger$z.trace(error);
|
|
2718
2719
|
this.doDisconnect(false);
|
|
2719
2720
|
}
|
|
2720
2721
|
else {
|
|
@@ -2723,46 +2724,46 @@ class SimulatorConnection extends Connection {
|
|
|
2723
2724
|
});
|
|
2724
2725
|
}
|
|
2725
2726
|
else {
|
|
2726
|
-
logger$
|
|
2727
|
+
logger$z.trace('tried to connect() a stopped connection');
|
|
2727
2728
|
}
|
|
2728
2729
|
}
|
|
2729
2730
|
handleIncomingData(data) {
|
|
2730
2731
|
if (!this.stopped) {
|
|
2731
|
-
logger$
|
|
2732
|
+
logger$z.trace('handleIncomingData() ' + protoToString(Message.fromBinary(data), Message));
|
|
2732
2733
|
this.emit('data', data);
|
|
2733
2734
|
}
|
|
2734
2735
|
else {
|
|
2735
|
-
logger$
|
|
2736
|
+
logger$z.trace('tried to call handleIncomingData() a stopped connection');
|
|
2736
2737
|
}
|
|
2737
2738
|
}
|
|
2738
2739
|
handleIncomingDisconnection() {
|
|
2739
2740
|
if (!this.stopped) {
|
|
2740
2741
|
const localNodeId = toNodeId(this.localPeerDescriptor);
|
|
2741
|
-
logger$
|
|
2742
|
+
logger$z.trace(localNodeId + ' handleIncomingDisconnection()');
|
|
2742
2743
|
this.stopped = true;
|
|
2743
2744
|
this.doDisconnect(false);
|
|
2744
2745
|
}
|
|
2745
2746
|
else {
|
|
2746
|
-
logger$
|
|
2747
|
+
logger$z.trace('tried to call handleIncomingDisconnection() a stopped connection');
|
|
2747
2748
|
}
|
|
2748
2749
|
}
|
|
2749
2750
|
destroy() {
|
|
2750
2751
|
const localNodeId = toNodeId(this.localPeerDescriptor);
|
|
2751
2752
|
if (!this.stopped) {
|
|
2752
|
-
logger$
|
|
2753
|
+
logger$z.trace(localNodeId + ' destroy()');
|
|
2753
2754
|
this.removeAllListeners();
|
|
2754
2755
|
this.close(false).catch((_e) => { });
|
|
2755
2756
|
}
|
|
2756
2757
|
else {
|
|
2757
|
-
logger$
|
|
2758
|
+
logger$z.trace(localNodeId + ' tried to call destroy() a stopped connection');
|
|
2758
2759
|
}
|
|
2759
2760
|
}
|
|
2760
2761
|
doDisconnect(gracefulLeave) {
|
|
2761
2762
|
const localNodeId = toNodeId(this.localPeerDescriptor);
|
|
2762
2763
|
const targetNodeId = toNodeId(this.targetPeerDescriptor);
|
|
2763
|
-
logger$
|
|
2764
|
+
logger$z.trace(localNodeId + ' doDisconnect()');
|
|
2764
2765
|
this.stopped = true;
|
|
2765
|
-
logger$
|
|
2766
|
+
logger$z.trace(localNodeId + ', ' + targetNodeId + ' doDisconnect emitting');
|
|
2766
2767
|
this.emit('disconnected', gracefulLeave);
|
|
2767
2768
|
}
|
|
2768
2769
|
}
|
|
@@ -2800,9 +2801,9 @@ const parseVersion = (version) => {
|
|
|
2800
2801
|
}
|
|
2801
2802
|
};
|
|
2802
2803
|
|
|
2803
|
-
var version = "103.
|
|
2804
|
+
var version = "103.6.0-rc.0";
|
|
2804
2805
|
|
|
2805
|
-
const logger$
|
|
2806
|
+
const logger$y = new Logger('Handshaker');
|
|
2806
2807
|
// Optimally the Outgoing and Incoming Handshakers could be their own separate classes
|
|
2807
2808
|
// However, in cases where the PeerDescriptor of the other end of the connection can be known
|
|
2808
2809
|
// only after a HandshakeRequest a base Handshaker class is needed as the IncomingHandshaker currently
|
|
@@ -2824,7 +2825,7 @@ const createOutgoingHandshaker = (localPeerDescriptor, pendingConnection, connec
|
|
|
2824
2825
|
}
|
|
2825
2826
|
};
|
|
2826
2827
|
const handshakeCompletedListener = (peerDescriptor) => {
|
|
2827
|
-
logger$
|
|
2828
|
+
logger$y.trace('handshake completed for outgoing connection, ' + toNodeId(peerDescriptor));
|
|
2828
2829
|
pendingConnection.onHandshakeCompleted(connection);
|
|
2829
2830
|
stopHandshaker();
|
|
2830
2831
|
};
|
|
@@ -2924,12 +2925,12 @@ class Handshaker extends EventEmitter {
|
|
|
2924
2925
|
try {
|
|
2925
2926
|
const message = Message.fromBinary(data);
|
|
2926
2927
|
if (message.body.oneofKind === 'handshakeRequest') {
|
|
2927
|
-
logger$
|
|
2928
|
+
logger$y.trace('handshake request received');
|
|
2928
2929
|
const handshake = message.body.handshakeRequest;
|
|
2929
2930
|
this.emit('handshakeRequest', handshake.sourcePeerDescriptor, handshake.protocolVersion, handshake.targetPeerDescriptor);
|
|
2930
2931
|
}
|
|
2931
2932
|
if (message.body.oneofKind === 'handshakeResponse') {
|
|
2932
|
-
logger$
|
|
2933
|
+
logger$y.trace('handshake response received');
|
|
2933
2934
|
const handshake = message.body.handshakeResponse;
|
|
2934
2935
|
const error = !isMaybeSupportedProtocolVersion(handshake.protocolVersion)
|
|
2935
2936
|
? HandshakeError.UNSUPPORTED_PROTOCOL_VERSION : handshake.error;
|
|
@@ -2942,18 +2943,18 @@ class Handshaker extends EventEmitter {
|
|
|
2942
2943
|
}
|
|
2943
2944
|
}
|
|
2944
2945
|
catch (err) {
|
|
2945
|
-
logger$
|
|
2946
|
+
logger$y.debug('error while parsing handshake message', err);
|
|
2946
2947
|
}
|
|
2947
2948
|
}
|
|
2948
2949
|
sendHandshakeRequest(remotePeerDescriptor) {
|
|
2949
2950
|
const msg = createHandshakeRequest(this.localPeerDescriptor, remotePeerDescriptor);
|
|
2950
2951
|
this.connection.send(Message.toBinary(msg));
|
|
2951
|
-
logger$
|
|
2952
|
+
logger$y.trace('handshake request sent');
|
|
2952
2953
|
}
|
|
2953
2954
|
sendHandshakeResponse(error) {
|
|
2954
2955
|
const msg = createHandshakeResponse(this.localPeerDescriptor, error);
|
|
2955
2956
|
this.connection.send(Message.toBinary(msg));
|
|
2956
|
-
logger$
|
|
2957
|
+
logger$y.trace('handshake response sent');
|
|
2957
2958
|
}
|
|
2958
2959
|
stop() {
|
|
2959
2960
|
this.connection.off('data', this.onDataListener);
|
|
@@ -2961,7 +2962,7 @@ class Handshaker extends EventEmitter {
|
|
|
2961
2962
|
}
|
|
2962
2963
|
}
|
|
2963
2964
|
|
|
2964
|
-
const logger$
|
|
2965
|
+
const logger$x = new Logger('PendingConnection');
|
|
2965
2966
|
// PendingConnection is used as a reference to a connection that should be opened and handshaked to a given PeerDescriptor
|
|
2966
2967
|
// It does not hold a connection internally. The public method onHandshakedCompleted should be called once a connection for the
|
|
2967
2968
|
// remotePeerDescriptor is opened and handshaked successfully.
|
|
@@ -2979,7 +2980,7 @@ class PendingConnection extends EventEmitter {
|
|
|
2979
2980
|
}, timeout, this.connectingAbortController.signal);
|
|
2980
2981
|
}
|
|
2981
2982
|
replaceAsDuplicate() {
|
|
2982
|
-
logger$
|
|
2983
|
+
logger$x.trace(getNodeIdOrUnknownFromPeerDescriptor(this.remotePeerDescriptor) + ' replaceAsDuplicate');
|
|
2983
2984
|
this.replacedAsDuplicate = true;
|
|
2984
2985
|
}
|
|
2985
2986
|
onHandshakeCompleted(connection) {
|
|
@@ -3010,7 +3011,7 @@ class PendingConnection extends EventEmitter {
|
|
|
3010
3011
|
}
|
|
3011
3012
|
}
|
|
3012
3013
|
|
|
3013
|
-
const logger$
|
|
3014
|
+
const logger$w = new Logger('SimulatorConnector');
|
|
3014
3015
|
class SimulatorConnector {
|
|
3015
3016
|
connectingConnections = new Map();
|
|
3016
3017
|
stopped = false;
|
|
@@ -3023,7 +3024,7 @@ class SimulatorConnector {
|
|
|
3023
3024
|
this.onNewConnection = onNewConnection;
|
|
3024
3025
|
}
|
|
3025
3026
|
connect(targetPeerDescriptor) {
|
|
3026
|
-
logger$
|
|
3027
|
+
logger$w.trace('connect() ' + toNodeId(targetPeerDescriptor));
|
|
3027
3028
|
const nodeId = toNodeId(targetPeerDescriptor);
|
|
3028
3029
|
const existingConnection = this.connectingConnections.get(nodeId);
|
|
3029
3030
|
if (existingConnection) {
|
|
@@ -3052,18 +3053,18 @@ class SimulatorConnector {
|
|
|
3052
3053
|
// connection is incoming, so remotePeerDescriptor is localPeerDescriptor
|
|
3053
3054
|
const remotePeerDescriptor = sourceConnection.localPeerDescriptor;
|
|
3054
3055
|
const remoteNodeId = toNodeId(sourceConnection.localPeerDescriptor);
|
|
3055
|
-
logger$
|
|
3056
|
+
logger$w.trace(remoteNodeId + ' incoming connection, stopped: ' + this.stopped);
|
|
3056
3057
|
if (this.stopped) {
|
|
3057
3058
|
return;
|
|
3058
3059
|
}
|
|
3059
3060
|
const connection = new SimulatorConnection(this.localPeerDescriptor, remotePeerDescriptor, ConnectionType.SIMULATOR_SERVER, this.simulator);
|
|
3060
3061
|
const pendingConnection = new PendingConnection(remotePeerDescriptor);
|
|
3061
3062
|
const handshaker = createIncomingHandshaker(this.localPeerDescriptor, pendingConnection, connection);
|
|
3062
|
-
logger$
|
|
3063
|
+
logger$w.trace('connected');
|
|
3063
3064
|
handshaker.once('handshakeRequest', () => {
|
|
3064
|
-
logger$
|
|
3065
|
+
logger$w.trace(remoteNodeId + ' incoming handshake request');
|
|
3065
3066
|
if (this.onNewConnection(pendingConnection)) {
|
|
3066
|
-
logger$
|
|
3067
|
+
logger$w.trace(remoteNodeId + ' calling acceptHandshake');
|
|
3067
3068
|
acceptHandshake(handshaker, pendingConnection, connection);
|
|
3068
3069
|
}
|
|
3069
3070
|
else {
|
|
@@ -3103,6 +3104,8 @@ class ListeningRpcCommunicator extends RoutingRpcCommunicator {
|
|
|
3103
3104
|
}
|
|
3104
3105
|
}
|
|
3105
3106
|
|
|
3107
|
+
const isWorkerEnvironment = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
|
|
3108
|
+
|
|
3106
3109
|
var RtcDescription;
|
|
3107
3110
|
(function (RtcDescription) {
|
|
3108
3111
|
RtcDescription["OFFER"] = "offer";
|
|
@@ -3117,8 +3120,8 @@ var DisconnectedRtcPeerConnectionStateEnum;
|
|
|
3117
3120
|
DisconnectedRtcPeerConnectionStateEnum["FAILED"] = "failed";
|
|
3118
3121
|
DisconnectedRtcPeerConnectionStateEnum["CLOSED"] = "closed";
|
|
3119
3122
|
})(DisconnectedRtcPeerConnectionStateEnum || (DisconnectedRtcPeerConnectionStateEnum = {}));
|
|
3120
|
-
const logger$
|
|
3121
|
-
class
|
|
3123
|
+
const logger$v = new Logger('DirectWebrtcConnection (browser)');
|
|
3124
|
+
class DirectWebrtcConnection extends EventEmitter {
|
|
3122
3125
|
connectionId;
|
|
3123
3126
|
connectionType = ConnectionType.WEBRTC;
|
|
3124
3127
|
// We need to keep track of connection state ourselves because
|
|
@@ -3156,7 +3159,7 @@ class WebrtcConnection extends EventEmitter {
|
|
|
3156
3159
|
}
|
|
3157
3160
|
};
|
|
3158
3161
|
this.peerConnection.onicegatheringstatechange = () => {
|
|
3159
|
-
logger$
|
|
3162
|
+
logger$v.trace(`conn.onGatheringStateChange: ${this.peerConnection?.iceGatheringState}`);
|
|
3160
3163
|
};
|
|
3161
3164
|
this.peerConnection.onconnectionstatechange = () => this.onStateChange();
|
|
3162
3165
|
if (isOffering) {
|
|
@@ -3167,7 +3170,7 @@ class WebrtcConnection extends EventEmitter {
|
|
|
3167
3170
|
await this.peerConnection.setLocalDescription();
|
|
3168
3171
|
}
|
|
3169
3172
|
catch (err) {
|
|
3170
|
-
logger$
|
|
3173
|
+
logger$v.warn('Failed to set local description', { err });
|
|
3171
3174
|
}
|
|
3172
3175
|
if (this.peerConnection.localDescription !== null) {
|
|
3173
3176
|
this.emit('localDescription', this.peerConnection.localDescription?.sdp, this.peerConnection.localDescription?.type);
|
|
@@ -3195,14 +3198,14 @@ class WebrtcConnection extends EventEmitter {
|
|
|
3195
3198
|
clearTimeout(this.earlyTimeout);
|
|
3196
3199
|
}
|
|
3197
3200
|
catch (err) {
|
|
3198
|
-
logger$
|
|
3201
|
+
logger$v.warn('Failed to set remote description', { err });
|
|
3199
3202
|
}
|
|
3200
3203
|
if ((type.toLowerCase() === RtcDescription.OFFER) && (this.peerConnection !== undefined)) {
|
|
3201
3204
|
try {
|
|
3202
3205
|
await this.peerConnection.setLocalDescription();
|
|
3203
3206
|
}
|
|
3204
3207
|
catch (err) {
|
|
3205
|
-
logger$
|
|
3208
|
+
logger$v.warn('Failed to set local description', { err });
|
|
3206
3209
|
}
|
|
3207
3210
|
if (this.peerConnection.localDescription !== null) {
|
|
3208
3211
|
this.emit('localDescription', this.peerConnection.localDescription.sdp, this.peerConnection.localDescription.type);
|
|
@@ -3212,7 +3215,7 @@ class WebrtcConnection extends EventEmitter {
|
|
|
3212
3215
|
addRemoteCandidate(candidate, mid) {
|
|
3213
3216
|
this.peerConnection?.addIceCandidate({ candidate: candidate, sdpMid: mid })
|
|
3214
3217
|
.catch((err) => {
|
|
3215
|
-
logger$
|
|
3218
|
+
logger$v.warn('Failed to add ICE candidate', { err });
|
|
3216
3219
|
});
|
|
3217
3220
|
}
|
|
3218
3221
|
isOpen() {
|
|
@@ -3235,7 +3238,7 @@ class WebrtcConnection extends EventEmitter {
|
|
|
3235
3238
|
this.dataChannel.close();
|
|
3236
3239
|
}
|
|
3237
3240
|
catch (err) {
|
|
3238
|
-
logger$
|
|
3241
|
+
logger$v.warn('Failed to close data channel', { err });
|
|
3239
3242
|
}
|
|
3240
3243
|
}
|
|
3241
3244
|
this.dataChannel = undefined;
|
|
@@ -3244,7 +3247,7 @@ class WebrtcConnection extends EventEmitter {
|
|
|
3244
3247
|
this.peerConnection.close();
|
|
3245
3248
|
}
|
|
3246
3249
|
catch (err) {
|
|
3247
|
-
logger$
|
|
3250
|
+
logger$v.warn('Failed to close connection', { err });
|
|
3248
3251
|
}
|
|
3249
3252
|
}
|
|
3250
3253
|
this.peerConnection = undefined;
|
|
@@ -3264,7 +3267,7 @@ class WebrtcConnection extends EventEmitter {
|
|
|
3264
3267
|
}
|
|
3265
3268
|
}
|
|
3266
3269
|
else {
|
|
3267
|
-
logger$
|
|
3270
|
+
logger$v.warn('Tried to send on a connection with last state ' + this.lastState);
|
|
3268
3271
|
}
|
|
3269
3272
|
}
|
|
3270
3273
|
setupDataChannel(dataChannel) {
|
|
@@ -3272,22 +3275,22 @@ class WebrtcConnection extends EventEmitter {
|
|
|
3272
3275
|
this.dataChannel.binaryType = 'arraybuffer';
|
|
3273
3276
|
this.dataChannel.bufferedAmountLowThreshold = this.bufferThresholdLow;
|
|
3274
3277
|
dataChannel.onopen = () => {
|
|
3275
|
-
logger$
|
|
3278
|
+
logger$v.trace('dc.onOpen');
|
|
3276
3279
|
this.onDataChannelOpen();
|
|
3277
3280
|
};
|
|
3278
3281
|
dataChannel.onclose = () => {
|
|
3279
|
-
logger$
|
|
3282
|
+
logger$v.trace('dc.onClosed');
|
|
3280
3283
|
this.doClose(false);
|
|
3281
3284
|
};
|
|
3282
3285
|
dataChannel.onerror = (err) => {
|
|
3283
|
-
logger$
|
|
3286
|
+
logger$v.warn('Data channel error', { err });
|
|
3284
3287
|
};
|
|
3285
3288
|
dataChannel.onmessage = (msg) => {
|
|
3286
|
-
logger$
|
|
3289
|
+
logger$v.trace('dc.onmessage');
|
|
3287
3290
|
this.emit('data', new Uint8Array(msg.data));
|
|
3288
3291
|
};
|
|
3289
3292
|
dataChannel.onbufferedamountlow = () => {
|
|
3290
|
-
logger$
|
|
3293
|
+
logger$v.trace('dc.onBufferedAmountLow');
|
|
3291
3294
|
while (this.messageQueue.length > 0 && this.dataChannel.bufferedAmount < this.bufferThresholdHigh) {
|
|
3292
3295
|
const data = this.messageQueue.shift();
|
|
3293
3296
|
this.dataChannel.send(data);
|
|
@@ -3326,6 +3329,431 @@ class WebrtcConnection extends EventEmitter {
|
|
|
3326
3329
|
}
|
|
3327
3330
|
}
|
|
3328
3331
|
|
|
3332
|
+
/**
|
|
3333
|
+
* WebrtcBridge — runs on the MAIN THREAD.
|
|
3334
|
+
*
|
|
3335
|
+
* Manages RTCPeerConnection instances on behalf of a worker that cannot
|
|
3336
|
+
* access them directly. Each logical connection is identified by a
|
|
3337
|
+
* `connectionId` string supplied by the worker.
|
|
3338
|
+
*
|
|
3339
|
+
* Signaling (ICE candidates, SDP offers/answers, connection-state changes)
|
|
3340
|
+
* is relayed to the worker through Comlink proxy callbacks.
|
|
3341
|
+
*
|
|
3342
|
+
* Once a DataChannel is created (offerer) or received (answerer) it is
|
|
3343
|
+
* **transferred** to the worker so that all data-path events fire inside
|
|
3344
|
+
* the worker's event loop — the main thread never touches data traffic.
|
|
3345
|
+
*/
|
|
3346
|
+
// ── Bridge implementation ───────────────────────────────────────────
|
|
3347
|
+
class WebrtcBridge {
|
|
3348
|
+
connections = new Map();
|
|
3349
|
+
async start(connectionId, iceServers, isOffering, callbacks) {
|
|
3350
|
+
const pc = new RTCPeerConnection({ iceServers });
|
|
3351
|
+
const conn = {
|
|
3352
|
+
pc,
|
|
3353
|
+
callbacks,
|
|
3354
|
+
isOffering,
|
|
3355
|
+
makingOffer: false,
|
|
3356
|
+
};
|
|
3357
|
+
this.connections.set(connectionId, conn);
|
|
3358
|
+
// ── ICE candidates ──────────────────────────────────────
|
|
3359
|
+
pc.onicecandidate = (event) => {
|
|
3360
|
+
if (event.candidate !== null && event.candidate.sdpMid !== null) {
|
|
3361
|
+
callbacks.onLocalCandidate(event.candidate.candidate, event.candidate.sdpMid);
|
|
3362
|
+
}
|
|
3363
|
+
};
|
|
3364
|
+
// ── Connection state → forwarded to worker ──────────────
|
|
3365
|
+
pc.onconnectionstatechange = () => {
|
|
3366
|
+
callbacks.onConnectionStateChange(pc.connectionState);
|
|
3367
|
+
};
|
|
3368
|
+
// ── Offerer path ────────────────────────────────────────
|
|
3369
|
+
if (isOffering) {
|
|
3370
|
+
pc.onnegotiationneeded = async () => {
|
|
3371
|
+
conn.makingOffer = true;
|
|
3372
|
+
try {
|
|
3373
|
+
await pc.setLocalDescription();
|
|
3374
|
+
}
|
|
3375
|
+
catch (_err) {
|
|
3376
|
+
// intentionally swallowed – mirrors DirectWebrtcConnection
|
|
3377
|
+
}
|
|
3378
|
+
if (pc.localDescription !== null) {
|
|
3379
|
+
callbacks.onLocalDescription(pc.localDescription.sdp, pc.localDescription.type);
|
|
3380
|
+
}
|
|
3381
|
+
conn.makingOffer = false;
|
|
3382
|
+
};
|
|
3383
|
+
const dc = pc.createDataChannel('streamrDataChannel');
|
|
3384
|
+
// Transfer DataChannel ownership to the worker immediately.
|
|
3385
|
+
// The worker will attach onopen/onclose/onmessage handlers.
|
|
3386
|
+
callbacks.onDataChannel(Comlink.transfer(dc, [dc]));
|
|
3387
|
+
}
|
|
3388
|
+
else {
|
|
3389
|
+
// ── Answerer path ───────────────────────────────────
|
|
3390
|
+
pc.ondatachannel = (event) => {
|
|
3391
|
+
callbacks.onDataChannel(Comlink.transfer(event.channel, [event.channel]));
|
|
3392
|
+
};
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
async setRemoteDescription(connectionId, description, type) {
|
|
3396
|
+
const conn = this.connections.get(connectionId);
|
|
3397
|
+
if (!conn) {
|
|
3398
|
+
return false;
|
|
3399
|
+
}
|
|
3400
|
+
const lowerType = type.toLowerCase();
|
|
3401
|
+
// Perfect-negotiation collision detection
|
|
3402
|
+
const offerCollision = lowerType === 'offer' &&
|
|
3403
|
+
(conn.makingOffer || conn.pc.signalingState !== 'stable');
|
|
3404
|
+
if (conn.isOffering && offerCollision) {
|
|
3405
|
+
return false;
|
|
3406
|
+
}
|
|
3407
|
+
try {
|
|
3408
|
+
await conn.pc.setRemoteDescription({ sdp: description, type: lowerType });
|
|
3409
|
+
}
|
|
3410
|
+
catch (_err) {
|
|
3411
|
+
return false;
|
|
3412
|
+
}
|
|
3413
|
+
// If we received an offer, create an answer
|
|
3414
|
+
if (lowerType === 'offer') {
|
|
3415
|
+
try {
|
|
3416
|
+
await conn.pc.setLocalDescription();
|
|
3417
|
+
}
|
|
3418
|
+
catch (_err) {
|
|
3419
|
+
// intentionally swallowed
|
|
3420
|
+
}
|
|
3421
|
+
if (conn.pc.localDescription !== null) {
|
|
3422
|
+
conn.callbacks.onLocalDescription(conn.pc.localDescription.sdp, conn.pc.localDescription.type);
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
return true;
|
|
3426
|
+
}
|
|
3427
|
+
async addRemoteCandidate(connectionId, candidate, mid) {
|
|
3428
|
+
const conn = this.connections.get(connectionId);
|
|
3429
|
+
if (!conn) {
|
|
3430
|
+
return;
|
|
3431
|
+
}
|
|
3432
|
+
try {
|
|
3433
|
+
await conn.pc.addIceCandidate({ candidate, sdpMid: mid });
|
|
3434
|
+
}
|
|
3435
|
+
catch (_err) {
|
|
3436
|
+
// intentionally swallowed
|
|
3437
|
+
}
|
|
3438
|
+
}
|
|
3439
|
+
async renameConnection(oldId, newId) {
|
|
3440
|
+
const conn = this.connections.get(oldId);
|
|
3441
|
+
if (conn) {
|
|
3442
|
+
this.connections.delete(oldId);
|
|
3443
|
+
this.connections.set(newId, conn);
|
|
3444
|
+
}
|
|
3445
|
+
}
|
|
3446
|
+
async close(connectionId) {
|
|
3447
|
+
const conn = this.connections.get(connectionId);
|
|
3448
|
+
if (!conn) {
|
|
3449
|
+
return;
|
|
3450
|
+
}
|
|
3451
|
+
this.connections.delete(connectionId);
|
|
3452
|
+
// Tear down event handlers
|
|
3453
|
+
conn.pc.onicecandidate = null;
|
|
3454
|
+
conn.pc.onconnectionstatechange = null;
|
|
3455
|
+
conn.pc.onnegotiationneeded = null;
|
|
3456
|
+
conn.pc.ondatachannel = null;
|
|
3457
|
+
try {
|
|
3458
|
+
conn.pc.close();
|
|
3459
|
+
}
|
|
3460
|
+
catch (_err) {
|
|
3461
|
+
// intentionally swallowed
|
|
3462
|
+
}
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
|
|
3466
|
+
/**
|
|
3467
|
+
* Call this function on the **main thread** before the worker starts using
|
|
3468
|
+
* WebRTC connections. It creates a dedicated `MessageChannel`, exposes a
|
|
3469
|
+
* {@link WebrtcBridge} instance on one port, and sends the other port to
|
|
3470
|
+
* the worker so that `WorkerWebrtcConnection` can reach the bridge.
|
|
3471
|
+
*
|
|
3472
|
+
* @example
|
|
3473
|
+
* ```ts
|
|
3474
|
+
* import { installWebrtcBridge } from '@streamr/dht'
|
|
3475
|
+
*
|
|
3476
|
+
* const worker = new Worker('./my-worker.ts', { type: 'module' })
|
|
3477
|
+
* installWebrtcBridge(worker)
|
|
3478
|
+
* ```
|
|
3479
|
+
*/
|
|
3480
|
+
const WEBRTC_BRIDGE_PORT_MESSAGE_TYPE = 'streamr-webrtc-bridge-port';
|
|
3481
|
+
function installWebrtcBridge(worker) {
|
|
3482
|
+
const bridge = new WebrtcBridge();
|
|
3483
|
+
const channel = new MessageChannel();
|
|
3484
|
+
// Expose the bridge API on port1 — the worker will Comlink.wrap(port2).
|
|
3485
|
+
Comlink.expose(bridge, channel.port1);
|
|
3486
|
+
// Send port2 to the worker. It is transferred (not cloned).
|
|
3487
|
+
worker.postMessage({ type: WEBRTC_BRIDGE_PORT_MESSAGE_TYPE, port: channel.port2 }, [channel.port2]);
|
|
3488
|
+
}
|
|
3489
|
+
|
|
3490
|
+
/**
|
|
3491
|
+
* WorkerWebrtcConnection — runs inside a **Web Worker**.
|
|
3492
|
+
*
|
|
3493
|
+
* Implements the same IWebrtcConnection + IConnection interfaces as
|
|
3494
|
+
* DirectWebrtcConnection, but delegates RTCPeerConnection management to
|
|
3495
|
+
* the main-thread {@link WebrtcBridge} via Comlink.
|
|
3496
|
+
*
|
|
3497
|
+
* The RTCDataChannel is **transferred** from the main thread and lives
|
|
3498
|
+
* entirely in the worker — all data events (onmessage, onopen, onclose,
|
|
3499
|
+
* onbufferedamountlow) fire in the worker's event loop. The main thread
|
|
3500
|
+
* is never involved in the data path.
|
|
3501
|
+
*/
|
|
3502
|
+
// ── Module-level bridge client (initialized once per worker) ────────
|
|
3503
|
+
let resolveBridgeProxy;
|
|
3504
|
+
const bridgeProxyPromise = new Promise((resolve) => {
|
|
3505
|
+
resolveBridgeProxy = resolve;
|
|
3506
|
+
});
|
|
3507
|
+
// Listen for the bridge port message from the main thread.
|
|
3508
|
+
// This is guarded so it only runs inside a worker context.
|
|
3509
|
+
if (isWorkerEnvironment) {
|
|
3510
|
+
const handler = (e) => {
|
|
3511
|
+
if (e.data?.type === WEBRTC_BRIDGE_PORT_MESSAGE_TYPE && e.data.port) {
|
|
3512
|
+
const proxy = Comlink.wrap(e.data.port);
|
|
3513
|
+
resolveBridgeProxy(proxy);
|
|
3514
|
+
self.removeEventListener('message', handler);
|
|
3515
|
+
}
|
|
3516
|
+
};
|
|
3517
|
+
self.addEventListener('message', handler);
|
|
3518
|
+
}
|
|
3519
|
+
function getBridgeProxy() {
|
|
3520
|
+
return bridgeProxyPromise;
|
|
3521
|
+
}
|
|
3522
|
+
// ── Disconnection states ────────────────────────────────────────────
|
|
3523
|
+
var DisconnectedState;
|
|
3524
|
+
(function (DisconnectedState) {
|
|
3525
|
+
DisconnectedState["DISCONNECTED"] = "disconnected";
|
|
3526
|
+
DisconnectedState["FAILED"] = "failed";
|
|
3527
|
+
DisconnectedState["CLOSED"] = "closed";
|
|
3528
|
+
})(DisconnectedState || (DisconnectedState = {}));
|
|
3529
|
+
const logger$u = new Logger('WorkerWebrtcConnection');
|
|
3530
|
+
// ── WorkerWebrtcConnection ──────────────────────────────────────────
|
|
3531
|
+
class WorkerWebrtcConnection extends EventEmitter {
|
|
3532
|
+
connectionId;
|
|
3533
|
+
connectionType = ConnectionType.WEBRTC;
|
|
3534
|
+
iceServers;
|
|
3535
|
+
bufferThresholdHigh;
|
|
3536
|
+
bufferThresholdLow;
|
|
3537
|
+
dataChannel;
|
|
3538
|
+
bridge;
|
|
3539
|
+
closed = false;
|
|
3540
|
+
connected = false;
|
|
3541
|
+
earlyTimeout;
|
|
3542
|
+
messageQueue = [];
|
|
3543
|
+
startPromise;
|
|
3544
|
+
constructor(params) {
|
|
3545
|
+
super();
|
|
3546
|
+
this.connectionId = createRandomConnectionId();
|
|
3547
|
+
this.iceServers = params.iceServers ?? [];
|
|
3548
|
+
this.bufferThresholdHigh = params.bufferThresholdHigh ?? 2 ** 17;
|
|
3549
|
+
this.bufferThresholdLow = params.bufferThresholdLow ?? 2 ** 15;
|
|
3550
|
+
this.earlyTimeout = setTimeout(() => {
|
|
3551
|
+
this.doClose(false, 'timed out due to remote descriptor not being set');
|
|
3552
|
+
}, EARLY_TIMEOUT);
|
|
3553
|
+
}
|
|
3554
|
+
// ── IWebrtcConnection ───────────────────────────────────────
|
|
3555
|
+
start(isOffering) {
|
|
3556
|
+
this.startPromise = this.doStart(isOffering);
|
|
3557
|
+
this.startPromise.catch((err) => {
|
|
3558
|
+
logger$u.warn('Failed to start worker WebRTC connection', { err });
|
|
3559
|
+
this.doClose(false, 'Failed to start');
|
|
3560
|
+
});
|
|
3561
|
+
}
|
|
3562
|
+
async doStart(isOffering) {
|
|
3563
|
+
this.bridge = await getBridgeProxy();
|
|
3564
|
+
const iceServers = this.iceServers.map(({ url, port, username, password }) => ({
|
|
3565
|
+
urls: `${url}:${port}`,
|
|
3566
|
+
username,
|
|
3567
|
+
credential: password,
|
|
3568
|
+
}));
|
|
3569
|
+
await this.bridge.start(this.connectionId, iceServers, isOffering, Comlink.proxy({
|
|
3570
|
+
onLocalCandidate: (candidate, mid) => {
|
|
3571
|
+
if (!this.closed) {
|
|
3572
|
+
this.emit('localCandidate', candidate, mid);
|
|
3573
|
+
}
|
|
3574
|
+
},
|
|
3575
|
+
onLocalDescription: (description, type) => {
|
|
3576
|
+
if (!this.closed) {
|
|
3577
|
+
this.emit('localDescription', description, type);
|
|
3578
|
+
}
|
|
3579
|
+
},
|
|
3580
|
+
onConnectionStateChange: (state) => {
|
|
3581
|
+
if (state === DisconnectedState.CLOSED ||
|
|
3582
|
+
state === DisconnectedState.DISCONNECTED ||
|
|
3583
|
+
state === DisconnectedState.FAILED) {
|
|
3584
|
+
this.doClose(false);
|
|
3585
|
+
}
|
|
3586
|
+
},
|
|
3587
|
+
onDataChannel: (channel) => {
|
|
3588
|
+
if (!this.closed) {
|
|
3589
|
+
this.setupDataChannel(channel);
|
|
3590
|
+
// If the channel was already open at transfer time
|
|
3591
|
+
if (channel.readyState === 'open') {
|
|
3592
|
+
this.onDataChannelOpen();
|
|
3593
|
+
}
|
|
3594
|
+
}
|
|
3595
|
+
},
|
|
3596
|
+
}));
|
|
3597
|
+
}
|
|
3598
|
+
async setRemoteDescription(description, type) {
|
|
3599
|
+
if (this.startPromise) {
|
|
3600
|
+
await this.startPromise;
|
|
3601
|
+
}
|
|
3602
|
+
if (!this.bridge || this.closed) {
|
|
3603
|
+
return;
|
|
3604
|
+
}
|
|
3605
|
+
const wasSet = await this.bridge.setRemoteDescription(this.connectionId, description, type);
|
|
3606
|
+
if (wasSet) {
|
|
3607
|
+
clearTimeout(this.earlyTimeout);
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3610
|
+
addRemoteCandidate(candidate, mid) {
|
|
3611
|
+
this.doAddRemoteCandidate(candidate, mid).catch((err) => {
|
|
3612
|
+
logger$u.warn('Failed to add remote candidate via bridge', { err });
|
|
3613
|
+
});
|
|
3614
|
+
}
|
|
3615
|
+
async doAddRemoteCandidate(candidate, mid) {
|
|
3616
|
+
if (this.startPromise) {
|
|
3617
|
+
await this.startPromise;
|
|
3618
|
+
}
|
|
3619
|
+
if (!this.bridge || this.closed) {
|
|
3620
|
+
return;
|
|
3621
|
+
}
|
|
3622
|
+
await this.bridge.addRemoteCandidate(this.connectionId, candidate, mid);
|
|
3623
|
+
}
|
|
3624
|
+
isOpen() {
|
|
3625
|
+
return this.connected;
|
|
3626
|
+
}
|
|
3627
|
+
// ── IConnection ─────────────────────────────────────────────
|
|
3628
|
+
async close(gracefulLeave, reason) {
|
|
3629
|
+
this.doClose(gracefulLeave, reason);
|
|
3630
|
+
}
|
|
3631
|
+
destroy() {
|
|
3632
|
+
this.removeAllListeners();
|
|
3633
|
+
this.doClose(false);
|
|
3634
|
+
}
|
|
3635
|
+
send(data) {
|
|
3636
|
+
if (this.connected && this.dataChannel) {
|
|
3637
|
+
if (this.dataChannel.bufferedAmount > this.bufferThresholdHigh) {
|
|
3638
|
+
this.messageQueue.push(data);
|
|
3639
|
+
}
|
|
3640
|
+
else {
|
|
3641
|
+
this.dataChannel.send(data);
|
|
3642
|
+
}
|
|
3643
|
+
}
|
|
3644
|
+
else if (!this.closed) {
|
|
3645
|
+
this.messageQueue.push(data);
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3648
|
+
setConnectionId(connectionId) {
|
|
3649
|
+
const oldId = this.connectionId;
|
|
3650
|
+
this.connectionId = connectionId;
|
|
3651
|
+
if (this.bridge && oldId !== connectionId) {
|
|
3652
|
+
this.bridge.renameConnection(oldId, connectionId).catch(() => { });
|
|
3653
|
+
}
|
|
3654
|
+
}
|
|
3655
|
+
// ── DataChannel handling (runs entirely in the worker) ──────
|
|
3656
|
+
setupDataChannel(dataChannel) {
|
|
3657
|
+
this.dataChannel = dataChannel;
|
|
3658
|
+
this.dataChannel.binaryType = 'arraybuffer';
|
|
3659
|
+
this.dataChannel.bufferedAmountLowThreshold = this.bufferThresholdLow;
|
|
3660
|
+
dataChannel.onopen = () => {
|
|
3661
|
+
logger$u.trace('dc.onOpen (worker)');
|
|
3662
|
+
this.onDataChannelOpen();
|
|
3663
|
+
};
|
|
3664
|
+
dataChannel.onclose = () => {
|
|
3665
|
+
logger$u.trace('dc.onClosed (worker)');
|
|
3666
|
+
this.doClose(false);
|
|
3667
|
+
};
|
|
3668
|
+
dataChannel.onerror = (err) => {
|
|
3669
|
+
logger$u.warn('Data channel error (worker)', { err });
|
|
3670
|
+
};
|
|
3671
|
+
dataChannel.onmessage = (msg) => {
|
|
3672
|
+
logger$u.trace('dc.onmessage (worker)');
|
|
3673
|
+
this.emit('data', new Uint8Array(msg.data));
|
|
3674
|
+
};
|
|
3675
|
+
dataChannel.onbufferedamountlow = () => {
|
|
3676
|
+
logger$u.trace('dc.onBufferedAmountLow (worker)');
|
|
3677
|
+
while (this.messageQueue.length > 0 &&
|
|
3678
|
+
this.dataChannel.bufferedAmount < this.bufferThresholdHigh) {
|
|
3679
|
+
const data = this.messageQueue.shift();
|
|
3680
|
+
this.dataChannel.send(data);
|
|
3681
|
+
}
|
|
3682
|
+
};
|
|
3683
|
+
}
|
|
3684
|
+
onDataChannelOpen() {
|
|
3685
|
+
this.connected = true;
|
|
3686
|
+
this.flushMessageQueue();
|
|
3687
|
+
this.emit('connected');
|
|
3688
|
+
}
|
|
3689
|
+
flushMessageQueue() {
|
|
3690
|
+
while (this.messageQueue.length > 0 &&
|
|
3691
|
+
this.dataChannel &&
|
|
3692
|
+
this.dataChannel.bufferedAmount < this.bufferThresholdHigh) {
|
|
3693
|
+
const data = this.messageQueue.shift();
|
|
3694
|
+
this.dataChannel.send(data);
|
|
3695
|
+
}
|
|
3696
|
+
}
|
|
3697
|
+
// ── Teardown ────────────────────────────────────────────────
|
|
3698
|
+
doClose(gracefulLeave, reason) {
|
|
3699
|
+
if (!this.closed) {
|
|
3700
|
+
this.closed = true;
|
|
3701
|
+
this.connected = false;
|
|
3702
|
+
this.messageQueue.length = 0;
|
|
3703
|
+
clearTimeout(this.earlyTimeout);
|
|
3704
|
+
this.stopListening();
|
|
3705
|
+
this.emit('disconnected', gracefulLeave, undefined, reason);
|
|
3706
|
+
this.removeAllListeners();
|
|
3707
|
+
if (this.dataChannel !== undefined) {
|
|
3708
|
+
try {
|
|
3709
|
+
this.dataChannel.close();
|
|
3710
|
+
}
|
|
3711
|
+
catch (err) {
|
|
3712
|
+
logger$u.warn('Failed to close data channel (worker)', { err });
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3715
|
+
this.dataChannel = undefined;
|
|
3716
|
+
// Tell the main-thread bridge to tear down the RTCPeerConnection.
|
|
3717
|
+
// Fire-and-forget — we don't block on this.
|
|
3718
|
+
this.bridge
|
|
3719
|
+
?.close(this.connectionId)
|
|
3720
|
+
.catch(() => {
|
|
3721
|
+
// intentionally swallowed
|
|
3722
|
+
});
|
|
3723
|
+
}
|
|
3724
|
+
}
|
|
3725
|
+
stopListening() {
|
|
3726
|
+
if (this.dataChannel !== undefined) {
|
|
3727
|
+
this.dataChannel.onopen = null;
|
|
3728
|
+
this.dataChannel.onclose = null;
|
|
3729
|
+
this.dataChannel.onerror = null;
|
|
3730
|
+
this.dataChannel.onbufferedamountlow = null;
|
|
3731
|
+
this.dataChannel.onmessage = null;
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
|
|
3736
|
+
/**
|
|
3737
|
+
* Conditional re-export of the browser WebrtcConnection.
|
|
3738
|
+
*
|
|
3739
|
+
* At module-load time we detect whether we are running inside a Web Worker.
|
|
3740
|
+
* - **Main thread** → use {@link DirectWebrtcConnection} which owns the
|
|
3741
|
+
* `RTCPeerConnection` and `RTCDataChannel` directly.
|
|
3742
|
+
* - **Worker thread** → use {@link WorkerWebrtcConnection} which delegates
|
|
3743
|
+
* `RTCPeerConnection` signaling to the main thread via a Comlink bridge
|
|
3744
|
+
* and receives a transferred `RTCDataChannel` that lives entirely in the
|
|
3745
|
+
* worker.
|
|
3746
|
+
*
|
|
3747
|
+
* Both classes implement `IWebrtcConnection & IConnection` and expose the
|
|
3748
|
+
* same public API, so upstream code (WebrtcConnector, etc.) is unaffected.
|
|
3749
|
+
*/
|
|
3750
|
+
// The constructor — points to the right class based on the runtime
|
|
3751
|
+
// environment. The type assertion is safe because both implementations
|
|
3752
|
+
// share the same public interface surface.
|
|
3753
|
+
const WebrtcConnection = (isWorkerEnvironment
|
|
3754
|
+
? WorkerWebrtcConnection
|
|
3755
|
+
: DirectWebrtcConnection);
|
|
3756
|
+
|
|
3329
3757
|
const logger$t = new Logger('WebrtcConnectorRpcRemote');
|
|
3330
3758
|
class WebrtcConnectorRpcRemote extends RpcRemote {
|
|
3331
3759
|
requestConnection() {
|
|
@@ -7608,5 +8036,5 @@ class SimulatorTransport extends ConnectionManager {
|
|
|
7608
8036
|
}
|
|
7609
8037
|
}
|
|
7610
8038
|
|
|
7611
|
-
export { ConnectionManager, ConnectionType, DataEntry, DefaultConnectorFacade, DhtCallContext, DhtNode, EXISTING_CONNECTION_TIMEOUT, LatencyType, ListeningRpcCommunicator, ManagedConnection, Message, NodeType, PeerDescriptor, PendingConnection, RoutingRpcCommunicator, RpcRemote, Simulator, SimulatorTransport, WebsocketClientConnection, areEqualPeerDescriptors, createOutgoingHandshaker, getRandomRegion, getRegionDelayMatrix, randomDhtAddress, toDhtAddress, toDhtAddressRaw, toNodeId };
|
|
8039
|
+
export { ConnectionManager, ConnectionType, DataEntry, DefaultConnectorFacade, DhtCallContext, DhtNode, EXISTING_CONNECTION_TIMEOUT, LatencyType, ListeningRpcCommunicator, ManagedConnection, Message, NodeType, PeerDescriptor, PendingConnection, RoutingRpcCommunicator, RpcRemote, Simulator, SimulatorTransport, WebsocketClientConnection, areEqualPeerDescriptors, createOutgoingHandshaker, getRandomRegion, getRegionDelayMatrix, installWebrtcBridge, randomDhtAddress, toDhtAddress, toDhtAddressRaw, toNodeId };
|
|
7612
8040
|
//# sourceMappingURL=exports-browser.js.map
|