@dxos/teleport 0.6.1-main.7c5f65a → 0.6.1-main.7d86e7f
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-A2USJKIQ.mjs → chunk-GHYLNW23.mjs} +47 -44
- package/dist/lib/browser/chunk-GHYLNW23.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +1 -1
- package/dist/lib/node/{chunk-XPYFDE6K.cjs → chunk-LEXW7IBY.cjs} +79 -76
- package/dist/lib/node/chunk-LEXW7IBY.cjs.map +7 -0
- package/dist/lib/node/index.cjs +11 -11
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +6 -6
- package/dist/lib/node/testing/index.cjs.map +1 -1
- package/dist/types/src/teleport.d.ts +1 -0
- package/dist/types/src/teleport.d.ts.map +1 -1
- package/dist/types/src/testing/test-builder.d.ts +1 -0
- package/dist/types/src/testing/test-builder.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/muxing/muxer.ts +1 -1
- package/src/teleport.ts +7 -0
- package/src/testing/test-builder.ts +5 -0
- package/dist/lib/browser/chunk-A2USJKIQ.mjs.map +0 -7
- package/dist/lib/node/chunk-XPYFDE6K.cjs.map +0 -7
@@ -9,6 +9,7 @@ import {
|
|
9
9
|
|
10
10
|
// packages/core/mesh/teleport/src/testing/test-builder.ts
|
11
11
|
import { pipeline } from "@dxos/node-std/stream";
|
12
|
+
import { waitForCondition } from "@dxos/async";
|
12
13
|
import { invariant as invariant5 } from "@dxos/invariant";
|
13
14
|
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
14
15
|
import { log as log6 } from "@dxos/log";
|
@@ -897,14 +898,6 @@ var Muxer = class {
|
|
897
898
|
}
|
898
899
|
async _sendCommand(cmd, channelId = -1, timeout = DEFAULT_SEND_COMMAND_TIMEOUT) {
|
899
900
|
if (this._disposed) {
|
900
|
-
log4.info("ignoring sendCommand after disposed", {
|
901
|
-
cmd
|
902
|
-
}, {
|
903
|
-
F: __dxlog_file4,
|
904
|
-
L: 400,
|
905
|
-
S: this,
|
906
|
-
C: (f, a) => f(...a)
|
907
|
-
});
|
908
901
|
return;
|
909
902
|
}
|
910
903
|
try {
|
@@ -1067,7 +1060,7 @@ var Teleport = class {
|
|
1067
1060
|
this._aborting = false;
|
1068
1061
|
invariant4(typeof initiator === "boolean", void 0, {
|
1069
1062
|
F: __dxlog_file5,
|
1070
|
-
L:
|
1063
|
+
L: 62,
|
1071
1064
|
S: this,
|
1072
1065
|
A: [
|
1073
1066
|
"typeof initiator === 'boolean'",
|
@@ -1076,7 +1069,7 @@ var Teleport = class {
|
|
1076
1069
|
});
|
1077
1070
|
invariant4(PublicKey.isPublicKey(localPeerId), void 0, {
|
1078
1071
|
F: __dxlog_file5,
|
1079
|
-
L:
|
1072
|
+
L: 63,
|
1080
1073
|
S: this,
|
1081
1074
|
A: [
|
1082
1075
|
"PublicKey.isPublicKey(localPeerId)",
|
@@ -1085,7 +1078,7 @@ var Teleport = class {
|
|
1085
1078
|
});
|
1086
1079
|
invariant4(PublicKey.isPublicKey(remotePeerId), void 0, {
|
1087
1080
|
F: __dxlog_file5,
|
1088
|
-
L:
|
1081
|
+
L: 64,
|
1089
1082
|
S: this,
|
1090
1083
|
A: [
|
1091
1084
|
"PublicKey.isPublicKey(remotePeerId)",
|
@@ -1104,13 +1097,13 @@ var Teleport = class {
|
|
1104
1097
|
}
|
1105
1098
|
log5.info("abort teleport due to onTimeout in ControlExtension", void 0, {
|
1106
1099
|
F: __dxlog_file5,
|
1107
|
-
L:
|
1100
|
+
L: 77,
|
1108
1101
|
S: this,
|
1109
1102
|
C: (f, a) => f(...a)
|
1110
1103
|
});
|
1111
1104
|
this.abort(new TimeoutError2("control extension")).catch((err) => log5.catch(err, void 0, {
|
1112
1105
|
F: __dxlog_file5,
|
1113
|
-
L:
|
1106
|
+
L: 78,
|
1114
1107
|
S: this,
|
1115
1108
|
C: (f, a) => f(...a)
|
1116
1109
|
}));
|
@@ -1121,13 +1114,13 @@ var Teleport = class {
|
|
1121
1114
|
name
|
1122
1115
|
}, {
|
1123
1116
|
F: __dxlog_file5,
|
1124
|
-
L:
|
1117
|
+
L: 86,
|
1125
1118
|
S: this,
|
1126
1119
|
C: (f, a) => f(...a)
|
1127
1120
|
});
|
1128
1121
|
invariant4(!this._remoteExtensions.has(name), "Remote extension already exists", {
|
1129
1122
|
F: __dxlog_file5,
|
1130
|
-
L:
|
1123
|
+
L: 87,
|
1131
1124
|
S: this,
|
1132
1125
|
A: [
|
1133
1126
|
"!this._remoteExtensions.has(name)",
|
@@ -1148,7 +1141,7 @@ var Teleport = class {
|
|
1148
1141
|
if (this._destroying || this._aborting) {
|
1149
1142
|
log5("destroy teleport due to muxer stream close, skipping due to already destroying/aborting", void 0, {
|
1150
1143
|
F: __dxlog_file5,
|
1151
|
-
L:
|
1144
|
+
L: 103,
|
1152
1145
|
S: this,
|
1153
1146
|
C: (f, a) => f(...a)
|
1154
1147
|
});
|
@@ -1171,12 +1164,15 @@ var Teleport = class {
|
|
1171
1164
|
channels: stats.channels
|
1172
1165
|
}, {
|
1173
1166
|
F: __dxlog_file5,
|
1174
|
-
L:
|
1167
|
+
L: 116,
|
1175
1168
|
S: this,
|
1176
1169
|
C: (f, a) => f(...a)
|
1177
1170
|
});
|
1178
1171
|
});
|
1179
1172
|
}
|
1173
|
+
get isOpen() {
|
1174
|
+
return this._open;
|
1175
|
+
}
|
1180
1176
|
get sessionIdString() {
|
1181
1177
|
return this._sessionId ? this._sessionId.truncate() : "none";
|
1182
1178
|
}
|
@@ -1193,7 +1189,7 @@ var Teleport = class {
|
|
1193
1189
|
this._sessionId = sessionId;
|
1194
1190
|
log5("open", void 0, {
|
1195
1191
|
F: __dxlog_file5,
|
1196
|
-
L:
|
1192
|
+
L: 150,
|
1197
1193
|
S: this,
|
1198
1194
|
C: (f, a) => f(...a)
|
1199
1195
|
});
|
@@ -1210,6 +1206,7 @@ var Teleport = class {
|
|
1210
1206
|
return;
|
1211
1207
|
}
|
1212
1208
|
this._aborting = true;
|
1209
|
+
this._open = false;
|
1213
1210
|
if (this._ctx.disposed) {
|
1214
1211
|
return;
|
1215
1212
|
}
|
@@ -1220,7 +1217,7 @@ var Teleport = class {
|
|
1220
1217
|
} catch (err2) {
|
1221
1218
|
log5.catch(err2, void 0, {
|
1222
1219
|
F: __dxlog_file5,
|
1223
|
-
L:
|
1220
|
+
L: 180,
|
1224
1221
|
S: this,
|
1225
1222
|
C: (f, a) => f(...a)
|
1226
1223
|
});
|
@@ -1236,11 +1233,12 @@ var Teleport = class {
|
|
1236
1233
|
extensionsCount: this._extensions.size
|
1237
1234
|
}, {
|
1238
1235
|
F: __dxlog_file5,
|
1239
|
-
L:
|
1236
|
+
L: 193,
|
1240
1237
|
S: this,
|
1241
1238
|
C: (f, a) => f(...a)
|
1242
1239
|
});
|
1243
1240
|
this._destroying = true;
|
1241
|
+
this._open = false;
|
1244
1242
|
if (this._ctx.disposed) {
|
1245
1243
|
return;
|
1246
1244
|
}
|
@@ -1251,7 +1249,7 @@ var Teleport = class {
|
|
1251
1249
|
name: extension.constructor.name
|
1252
1250
|
}, {
|
1253
1251
|
F: __dxlog_file5,
|
1254
|
-
L:
|
1252
|
+
L: 205,
|
1255
1253
|
S: this,
|
1256
1254
|
C: (f, a) => f(...a)
|
1257
1255
|
});
|
@@ -1260,14 +1258,14 @@ var Teleport = class {
|
|
1260
1258
|
name: extension.constructor.name
|
1261
1259
|
}, {
|
1262
1260
|
F: __dxlog_file5,
|
1263
|
-
L:
|
1261
|
+
L: 207,
|
1264
1262
|
S: this,
|
1265
1263
|
C: (f, a) => f(...a)
|
1266
1264
|
});
|
1267
1265
|
} catch (err2) {
|
1268
1266
|
log5.catch(err2, void 0, {
|
1269
1267
|
F: __dxlog_file5,
|
1270
|
-
L:
|
1268
|
+
L: 209,
|
1271
1269
|
S: this,
|
1272
1270
|
C: (f, a) => f(...a)
|
1273
1271
|
});
|
@@ -1276,7 +1274,7 @@ var Teleport = class {
|
|
1276
1274
|
await this._muxer.close();
|
1277
1275
|
log5("teleport destroyed", void 0, {
|
1278
1276
|
F: __dxlog_file5,
|
1279
|
-
L:
|
1277
|
+
L: 214,
|
1280
1278
|
S: this,
|
1281
1279
|
C: (f, a) => f(...a)
|
1282
1280
|
});
|
@@ -1289,7 +1287,7 @@ var Teleport = class {
|
|
1289
1287
|
name
|
1290
1288
|
}, {
|
1291
1289
|
F: __dxlog_file5,
|
1292
|
-
L:
|
1290
|
+
L: 222,
|
1293
1291
|
S: this,
|
1294
1292
|
C: (f, a) => f(...a)
|
1295
1293
|
});
|
@@ -1313,7 +1311,7 @@ var Teleport = class {
|
|
1313
1311
|
_setExtension(extensionName, extension) {
|
1314
1312
|
invariant4(!extensionName.includes("/"), "Invalid extension name", {
|
1315
1313
|
F: __dxlog_file5,
|
1316
|
-
L:
|
1314
|
+
L: 246,
|
1317
1315
|
S: this,
|
1318
1316
|
A: [
|
1319
1317
|
"!extensionName.includes('/')",
|
@@ -1322,7 +1320,7 @@ var Teleport = class {
|
|
1322
1320
|
});
|
1323
1321
|
invariant4(!this._extensions.has(extensionName), "Extension already exists", {
|
1324
1322
|
F: __dxlog_file5,
|
1325
|
-
L:
|
1323
|
+
L: 247,
|
1326
1324
|
S: this,
|
1327
1325
|
A: [
|
1328
1326
|
"!this._extensions.has(extensionName)",
|
@@ -1336,7 +1334,7 @@ var Teleport = class {
|
|
1336
1334
|
extensionName
|
1337
1335
|
}, {
|
1338
1336
|
F: __dxlog_file5,
|
1339
|
-
L:
|
1337
|
+
L: 252,
|
1340
1338
|
S: this,
|
1341
1339
|
C: (f, a) => f(...a)
|
1342
1340
|
});
|
@@ -1348,7 +1346,7 @@ var Teleport = class {
|
|
1348
1346
|
createPort: async (channelName, opts) => {
|
1349
1347
|
invariant4(!channelName.includes("/"), "Invalid channel name", {
|
1350
1348
|
F: __dxlog_file5,
|
1351
|
-
L:
|
1349
|
+
L: 260,
|
1352
1350
|
S: this,
|
1353
1351
|
A: [
|
1354
1352
|
"!channelName.includes('/')",
|
@@ -1360,7 +1358,7 @@ var Teleport = class {
|
|
1360
1358
|
createStream: async (channelName, opts) => {
|
1361
1359
|
invariant4(!channelName.includes("/"), "Invalid channel name", {
|
1362
1360
|
F: __dxlog_file5,
|
1363
|
-
L:
|
1361
|
+
L: 264,
|
1364
1362
|
S: this,
|
1365
1363
|
A: [
|
1366
1364
|
"!channelName.includes('/')",
|
@@ -1380,7 +1378,7 @@ var Teleport = class {
|
|
1380
1378
|
extensionName
|
1381
1379
|
}, {
|
1382
1380
|
F: __dxlog_file5,
|
1383
|
-
L:
|
1381
|
+
L: 275,
|
1384
1382
|
S: this,
|
1385
1383
|
C: (f, a) => f(...a)
|
1386
1384
|
});
|
@@ -1418,7 +1416,7 @@ var TestBuilder = class {
|
|
1418
1416
|
async connect(peer1, peer2) {
|
1419
1417
|
invariant5(peer1 !== peer2, void 0, {
|
1420
1418
|
F: __dxlog_file6,
|
1421
|
-
L:
|
1419
|
+
L: 38,
|
1422
1420
|
S: this,
|
1423
1421
|
A: [
|
1424
1422
|
"peer1 !== peer2",
|
@@ -1427,7 +1425,7 @@ var TestBuilder = class {
|
|
1427
1425
|
});
|
1428
1426
|
invariant5(this._peers.has(peer1), void 0, {
|
1429
1427
|
F: __dxlog_file6,
|
1430
|
-
L:
|
1428
|
+
L: 39,
|
1431
1429
|
S: this,
|
1432
1430
|
A: [
|
1433
1431
|
"this._peers.has(peer1)",
|
@@ -1436,7 +1434,7 @@ var TestBuilder = class {
|
|
1436
1434
|
});
|
1437
1435
|
invariant5(this._peers.has(peer1), void 0, {
|
1438
1436
|
F: __dxlog_file6,
|
1439
|
-
L:
|
1437
|
+
L: 40,
|
1440
1438
|
S: this,
|
1441
1439
|
A: [
|
1442
1440
|
"this._peers.has(peer1)",
|
@@ -1464,7 +1462,7 @@ var TestBuilder = class {
|
|
1464
1462
|
async disconnect(peer1, peer2) {
|
1465
1463
|
invariant5(peer1 !== peer2, void 0, {
|
1466
1464
|
F: __dxlog_file6,
|
1467
|
-
L:
|
1465
|
+
L: 52,
|
1468
1466
|
S: this,
|
1469
1467
|
A: [
|
1470
1468
|
"peer1 !== peer2",
|
@@ -1473,7 +1471,7 @@ var TestBuilder = class {
|
|
1473
1471
|
});
|
1474
1472
|
invariant5(this._peers.has(peer1), void 0, {
|
1475
1473
|
F: __dxlog_file6,
|
1476
|
-
L:
|
1474
|
+
L: 53,
|
1477
1475
|
S: this,
|
1478
1476
|
A: [
|
1479
1477
|
"this._peers.has(peer1)",
|
@@ -1482,7 +1480,7 @@ var TestBuilder = class {
|
|
1482
1480
|
});
|
1483
1481
|
invariant5(this._peers.has(peer1), void 0, {
|
1484
1482
|
F: __dxlog_file6,
|
1485
|
-
L:
|
1483
|
+
L: 54,
|
1486
1484
|
S: this,
|
1487
1485
|
A: [
|
1488
1486
|
"this._peers.has(peer1)",
|
@@ -1493,7 +1491,7 @@ var TestBuilder = class {
|
|
1493
1491
|
const connection2 = Array.from(peer2.connections).find((connection) => connection.remotePeerId.equals(peer1.peerId));
|
1494
1492
|
invariant5(connection1, void 0, {
|
1495
1493
|
F: __dxlog_file6,
|
1496
|
-
L:
|
1494
|
+
L: 63,
|
1497
1495
|
S: this,
|
1498
1496
|
A: [
|
1499
1497
|
"connection1",
|
@@ -1502,7 +1500,7 @@ var TestBuilder = class {
|
|
1502
1500
|
});
|
1503
1501
|
invariant5(connection2, void 0, {
|
1504
1502
|
F: __dxlog_file6,
|
1505
|
-
L:
|
1503
|
+
L: 64,
|
1506
1504
|
S: this,
|
1507
1505
|
A: [
|
1508
1506
|
"connection2",
|
@@ -1532,7 +1530,7 @@ var TestPeer = class {
|
|
1532
1530
|
async openConnection(connection) {
|
1533
1531
|
invariant5(this.connections.has(connection), void 0, {
|
1534
1532
|
F: __dxlog_file6,
|
1535
|
-
L:
|
1533
|
+
L: 85,
|
1536
1534
|
S: this,
|
1537
1535
|
A: [
|
1538
1536
|
"this.connections.has(connection)",
|
@@ -1545,7 +1543,7 @@ var TestPeer = class {
|
|
1545
1543
|
async closeConnection(connection) {
|
1546
1544
|
invariant5(this.connections.has(connection), void 0, {
|
1547
1545
|
F: __dxlog_file6,
|
1548
|
-
L:
|
1546
|
+
L: 91,
|
1549
1547
|
S: this,
|
1550
1548
|
A: [
|
1551
1549
|
"this.connections.has(connection)",
|
@@ -1567,7 +1565,7 @@ var pipeStreams = (stream1, stream2) => {
|
|
1567
1565
|
if (err && err.code !== "ERR_STREAM_PREMATURE_CLOSE") {
|
1568
1566
|
log6.catch(err, void 0, {
|
1569
1567
|
F: __dxlog_file6,
|
1570
|
-
L:
|
1568
|
+
L: 107,
|
1571
1569
|
S: void 0,
|
1572
1570
|
C: (f, a) => f(...a)
|
1573
1571
|
});
|
@@ -1577,7 +1575,7 @@ var pipeStreams = (stream1, stream2) => {
|
|
1577
1575
|
if (err && err.code !== "ERR_STREAM_PREMATURE_CLOSE") {
|
1578
1576
|
log6.catch(err, void 0, {
|
1579
1577
|
F: __dxlog_file6,
|
1580
|
-
L:
|
1578
|
+
L: 112,
|
1581
1579
|
S: void 0,
|
1582
1580
|
C: (f, a) => f(...a)
|
1583
1581
|
});
|
@@ -1595,6 +1593,11 @@ var TestConnection = class {
|
|
1595
1593
|
remotePeerId
|
1596
1594
|
});
|
1597
1595
|
}
|
1596
|
+
whenOpen(open) {
|
1597
|
+
return waitForCondition({
|
1598
|
+
condition: () => this.teleport.isOpen === open
|
1599
|
+
});
|
1600
|
+
}
|
1598
1601
|
};
|
1599
1602
|
|
1600
1603
|
// packages/core/mesh/teleport/src/testing/test-extension.ts
|
@@ -1975,4 +1978,4 @@ export {
|
|
1975
1978
|
TestExtension,
|
1976
1979
|
TestExtensionWithStreams
|
1977
1980
|
};
|
1978
|
-
//# sourceMappingURL=chunk-
|
1981
|
+
//# sourceMappingURL=chunk-GHYLNW23.mjs.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../../../src/testing/test-builder.ts", "../../../src/teleport.ts", "../../../src/control-extension.ts", "../../../src/muxing/framer.ts", "../../../src/muxing/muxer.ts", "../../../src/muxing/balancer.ts", "../../../src/testing/test-extension.ts", "../../../src/testing/test-extension-with-streams.ts"],
|
4
|
+
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { type Duplex, pipeline } from 'node:stream';\n\nimport { waitForCondition } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { Teleport } from '../teleport';\n\ntype CreatePeerOpts<T extends TestPeer> = {\n factory: () => T;\n};\n\nexport class TestBuilder {\n private readonly _peers = new Set<TestPeer>();\n\n createPeer<T extends TestPeer>(opts: CreatePeerOpts<T>): T {\n const peer = opts.factory();\n this._peers.add(peer);\n return peer;\n }\n\n *createPeers<T extends TestPeer>(opts: CreatePeerOpts<T>): Generator<T> {\n while (true) {\n yield this.createPeer(opts);\n }\n }\n\n async destroy() {\n await Promise.all(Array.from(this._peers).map((agent) => agent.destroy()));\n }\n\n async connect(peer1: TestPeer, peer2: TestPeer) {\n invariant(peer1 !== peer2);\n invariant(this._peers.has(peer1));\n invariant(this._peers.has(peer1));\n\n const connection1 = peer1.createConnection({ initiator: true, remotePeerId: peer2.peerId });\n const connection2 = peer2.createConnection({ initiator: false, remotePeerId: peer1.peerId });\n\n pipeStreams(connection1.teleport.stream, connection2.teleport.stream);\n await Promise.all([peer1.openConnection(connection1), peer2.openConnection(connection2)]);\n\n return [connection1, connection2];\n }\n\n async disconnect(peer1: TestPeer, peer2: TestPeer) {\n invariant(peer1 !== peer2);\n invariant(this._peers.has(peer1));\n invariant(this._peers.has(peer1));\n\n const connection1 = Array.from(peer1.connections).find((connection) =>\n connection.remotePeerId.equals(peer2.peerId),\n );\n const connection2 = Array.from(peer2.connections).find((connection) =>\n connection.remotePeerId.equals(peer1.peerId),\n );\n\n invariant(connection1);\n invariant(connection2);\n\n await Promise.all([peer1.closeConnection(connection1), peer2.closeConnection(connection2)]);\n }\n}\n\nexport class TestPeer {\n public readonly connections = new Set<TestConnection>();\n\n constructor(public readonly peerId: PublicKey = PublicKey.random()) {}\n\n protected async onOpen(connection: TestConnection) {}\n protected async onClose(connection: TestConnection) {}\n\n createConnection({ initiator, remotePeerId }: { initiator: boolean; remotePeerId: PublicKey }) {\n const connection = new TestConnection(this.peerId, remotePeerId, initiator);\n this.connections.add(connection);\n return connection;\n }\n\n async openConnection(connection: TestConnection) {\n invariant(this.connections.has(connection));\n await connection.teleport.open(PublicKey.random());\n await this.onOpen(connection);\n }\n\n async closeConnection(connection: TestConnection) {\n invariant(this.connections.has(connection));\n await this.onClose(connection);\n await connection.teleport.close();\n this.connections.delete(connection);\n }\n\n async destroy() {\n for (const teleport of this.connections) {\n await this.closeConnection(teleport);\n }\n }\n}\n\nconst pipeStreams = (stream1: Duplex, stream2: Duplex) => {\n pipeline(stream1, stream2, (err) => {\n if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {\n log.catch(err);\n }\n });\n pipeline(stream2, stream1, (err) => {\n if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {\n log.catch(err);\n }\n });\n};\n\nexport class TestConnection {\n public teleport: Teleport;\n\n constructor(\n public readonly localPeerId: PublicKey,\n public readonly remotePeerId: PublicKey,\n public readonly initiator: boolean,\n ) {\n this.teleport = new Teleport({\n initiator,\n localPeerId,\n remotePeerId,\n });\n }\n\n public whenOpen(open: boolean) {\n return waitForCondition({ condition: () => this.teleport.isOpen === open });\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { type Duplex } from 'node:stream';\n\nimport { runInContextAsync, synchronized, scheduleTask, type Event } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { failUndefined } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { RpcClosedError, TimeoutError } from '@dxos/protocols';\n\nimport { ControlExtension } from './control-extension';\nimport { type CreateChannelOpts, Muxer, type MuxerStats, type RpcPort } from './muxing';\n\nexport type TeleportParams = {\n initiator: boolean;\n localPeerId: PublicKey;\n remotePeerId: PublicKey;\n controlHeartbeatInterval?: number;\n controlHeartbeatTimeout?: number;\n};\n\nconst CONTROL_HEARTBEAT_INTERVAL = 10_000;\nconst CONTROL_HEARTBEAT_TIMEOUT = 60_000;\n\n/**\n * TODO(burdon): Comment: what is this?\n */\nexport class Teleport {\n public readonly initiator: boolean;\n public readonly localPeerId: PublicKey;\n public readonly remotePeerId: PublicKey;\n public _sessionId?: PublicKey;\n\n private readonly _ctx = new Context({\n onError: (err) => {\n void this.destroy(err).catch(() => {\n log.error('Error during destroy', err);\n });\n },\n });\n\n private readonly _muxer = new Muxer();\n\n private readonly _control;\n\n private readonly _extensions = new Map<string, TeleportExtension>();\n private readonly _remoteExtensions = new Set<string>();\n\n private _open = false;\n private _destroying = false;\n private _aborting = false;\n\n public get isOpen() {\n return this._open;\n }\n\n constructor({ initiator, localPeerId, remotePeerId, ...rest }: TeleportParams) {\n invariant(typeof initiator === 'boolean');\n invariant(PublicKey.isPublicKey(localPeerId));\n invariant(PublicKey.isPublicKey(remotePeerId));\n this.initiator = initiator;\n this.localPeerId = localPeerId;\n this.remotePeerId = remotePeerId;\n\n this._control = new ControlExtension(\n {\n heartbeatInterval: rest.controlHeartbeatInterval ?? CONTROL_HEARTBEAT_INTERVAL,\n heartbeatTimeout: rest.controlHeartbeatTimeout ?? CONTROL_HEARTBEAT_TIMEOUT,\n onTimeout: () => {\n if (this._destroying || this._aborting) {\n return;\n }\n log.info('abort teleport due to onTimeout in ControlExtension');\n this.abort(new TimeoutError('control extension')).catch((err) => log.catch(err));\n },\n },\n this.localPeerId,\n this.remotePeerId,\n );\n\n this._control.onExtensionRegistered.set(async (name) => {\n log('remote extension', { name });\n invariant(!this._remoteExtensions.has(name), 'Remote extension already exists');\n this._remoteExtensions.add(name);\n\n if (this._extensions.has(name)) {\n try {\n await this._openExtension(name);\n } catch (err: any) {\n await this.destroy(err);\n }\n }\n });\n\n {\n // Destroy Teleport when the stream is closed.\n this._muxer.stream.on('close', async () => {\n if (this._destroying || this._aborting) {\n log('destroy teleport due to muxer stream close, skipping due to already destroying/aborting');\n return;\n }\n await this.destroy();\n });\n\n this._muxer.stream.on('error', async (err) => {\n await this.destroy(err);\n });\n }\n\n // let last: MuxerStats | undefined;\n this._muxer.statsUpdated.on((stats) => {\n log.trace('dxos.mesh.teleport.stats', {\n localPeerId,\n remotePeerId,\n bytesSent: stats.bytesSent,\n bytesSentRate: stats.bytesSentRate,\n bytesReceived: stats.bytesReceived,\n bytesReceivedRate: stats.bytesReceivedRate,\n channels: stats.channels,\n });\n\n // last = stats;\n });\n }\n\n @logInfo\n get sessionIdString(): string {\n return this._sessionId ? this._sessionId.truncate() : 'none';\n }\n\n get stream(): Duplex {\n return this._muxer.stream;\n }\n\n get stats(): Event<MuxerStats> {\n return this._muxer.statsUpdated;\n }\n\n /**\n * Blocks until the handshake is complete.\n */\n\n async open(sessionId: PublicKey = PublicKey.random()) {\n // invariant(sessionId);\n this._sessionId = sessionId;\n log('open');\n this._setExtension('dxos.mesh.teleport.control', this._control);\n await this._openExtension('dxos.mesh.teleport.control');\n this._open = true;\n this._muxer.setSessionId(sessionId);\n }\n\n async close(err?: Error) {\n // TODO(dmaretskyi): Try soft close.\n await this.destroy(err);\n }\n\n @synchronized\n async abort(err?: Error) {\n if (this._aborting || this._destroying) {\n return;\n }\n this._aborting = true;\n this._open = false;\n\n if (this._ctx.disposed) {\n return;\n }\n\n await this._ctx.dispose();\n\n for (const extension of this._extensions.values()) {\n try {\n await extension.onAbort(err);\n } catch (err: any) {\n log.catch(err);\n }\n }\n\n await this._muxer.destroy(err);\n }\n\n @synchronized\n // TODO(nf): analyze callers and consider abort instead\n async destroy(err?: Error) {\n if (this._destroying || this._aborting) {\n return;\n }\n log('destroying teleport...', { extensionsCount: this._extensions.size });\n this._destroying = true;\n this._open = false;\n\n if (this._ctx.disposed) {\n return;\n }\n\n await this._ctx.dispose();\n\n for (const extension of this._extensions.values()) {\n try {\n log('destroying extension', { name: extension.constructor.name });\n await extension.onClose(err);\n log('destroyed extension', { name: extension.constructor.name });\n } catch (err: any) {\n log.catch(err);\n }\n }\n\n await this._muxer.close();\n log('teleport destroyed');\n }\n\n addExtension(name: string, extension: TeleportExtension) {\n if (!this._open) {\n throw new Error('Not open');\n }\n\n log('addExtension', { name });\n this._setExtension(name, extension);\n\n // Perform the registration in a separate tick as this might block while the remote side is opening the extension.\n scheduleTask(this._ctx, async () => {\n try {\n await this._control.registerExtension(name);\n } catch (err) {\n if (err instanceof RpcClosedError) {\n return;\n }\n throw err;\n }\n });\n\n if (this._remoteExtensions.has(name)) {\n // Open the extension in a separate tick.\n scheduleTask(this._ctx, async () => {\n await this._openExtension(name);\n });\n }\n }\n\n private _setExtension(extensionName: string, extension: TeleportExtension) {\n invariant(!extensionName.includes('/'), 'Invalid extension name');\n invariant(!this._extensions.has(extensionName), 'Extension already exists');\n this._extensions.set(extensionName, extension);\n }\n\n private async _openExtension(extensionName: string) {\n log('open extension', { extensionName });\n const extension = this._extensions.get(extensionName) ?? failUndefined();\n\n const context: ExtensionContext = {\n initiator: this.initiator,\n localPeerId: this.localPeerId,\n remotePeerId: this.remotePeerId,\n createPort: async (channelName: string, opts?: CreateChannelOpts) => {\n invariant(!channelName.includes('/'), 'Invalid channel name');\n return this._muxer.createPort(`${extensionName}/${channelName}`, opts);\n },\n createStream: async (channelName: string, opts?: CreateChannelOpts) => {\n invariant(!channelName.includes('/'), 'Invalid channel name');\n return this._muxer.createStream(`${extensionName}/${channelName}`, opts);\n },\n close: (err) => {\n void runInContextAsync(this._ctx, async () => {\n await this.close(err);\n });\n },\n };\n\n await extension.onOpen(context);\n log('extension opened', { extensionName });\n }\n}\n\nexport type ExtensionContext = {\n /**\n * One of the peers will be designated an initiator.\n */\n initiator: boolean;\n localPeerId: PublicKey;\n remotePeerId: PublicKey;\n createStream(tag: string, opts?: CreateChannelOpts): Promise<Duplex>;\n createPort(tag: string, opts?: CreateChannelOpts): Promise<RpcPort>;\n close(err?: Error): void;\n};\n\nexport interface TeleportExtension {\n onOpen(context: ExtensionContext): Promise<void>;\n onClose(err?: Error): Promise<void>;\n onAbort(err?: Error): Promise<void>;\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { asyncTimeout, scheduleTaskInterval, TimeoutError as AsyncTimeoutError } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { schema, RpcClosedError } from '@dxos/protocols';\nimport { type ControlService } from '@dxos/protocols/proto/dxos/mesh/teleport/control';\nimport { createProtoRpcPeer, type ProtoRpcPeer } from '@dxos/rpc';\nimport { Callback } from '@dxos/util';\n\nimport { type ExtensionContext, type TeleportExtension } from './teleport';\n\nconst HEARTBEAT_RTT_WARN_THRESH = 10_000;\nconst DEBUG_PRINT_HEARTBEAT = false; // very noisy\n\ntype ControlRpcBundle = {\n Control: ControlService;\n};\n\ntype ControlExtensionOpts = {\n heartbeatInterval: number;\n heartbeatTimeout: number;\n onTimeout: (err: any) => void;\n};\n\nexport class ControlExtension implements TeleportExtension {\n private readonly _ctx = new Context({\n onError: (err) => {\n this._extensionContext.close(err);\n },\n });\n\n public readonly onExtensionRegistered = new Callback<(extensionName: string) => void>();\n\n private _extensionContext!: ExtensionContext;\n private _rpc!: ProtoRpcPeer<{ Control: ControlService }>;\n\n constructor(\n private readonly opts: ControlExtensionOpts,\n private readonly localPeerId: PublicKey,\n private readonly remotePeerId: PublicKey,\n ) {}\n\n async registerExtension(name: string) {\n await this._rpc.rpc.Control.registerExtension({ name });\n }\n\n async onOpen(extensionContext: ExtensionContext): Promise<void> {\n this._extensionContext = extensionContext;\n\n this._rpc = createProtoRpcPeer<ControlRpcBundle, ControlRpcBundle>({\n requested: {\n Control: schema.getService('dxos.mesh.teleport.control.ControlService'),\n },\n exposed: {\n Control: schema.getService('dxos.mesh.teleport.control.ControlService'),\n },\n handlers: {\n Control: {\n registerExtension: async (request) => {\n this.onExtensionRegistered.call(request.name);\n },\n heartbeat: async (request) => {\n if (DEBUG_PRINT_HEARTBEAT) {\n log('received heartbeat request', {\n ts: request.requestTimestamp,\n localPeerId: this.localPeerId.truncate(),\n remotePeerId: this.remotePeerId.truncate(),\n });\n }\n return {\n requestTimestamp: request.requestTimestamp,\n };\n },\n },\n },\n port: await extensionContext.createPort('rpc', {\n contentType: 'application/x-protobuf; messageType=\"dxos.rpc.Message\"',\n }),\n timeout: this.opts.heartbeatTimeout,\n });\n\n await this._rpc.open();\n\n scheduleTaskInterval(\n this._ctx,\n async () => {\n const reqTS = new Date();\n try {\n const resp = await asyncTimeout(\n this._rpc.rpc.Control.heartbeat({ requestTimestamp: reqTS }),\n this.opts.heartbeatTimeout,\n );\n const now = Date.now();\n // TODO(nf): properly instrument\n if (resp.requestTimestamp instanceof Date) {\n if (\n now - resp.requestTimestamp.getTime() >\n (HEARTBEAT_RTT_WARN_THRESH < this.opts.heartbeatTimeout\n ? HEARTBEAT_RTT_WARN_THRESH\n : this.opts.heartbeatTimeout / 2)\n ) {\n log.warn(`heartbeat RTT for Teleport > ${HEARTBEAT_RTT_WARN_THRESH / 1000}s`, {\n rtt: now - resp.requestTimestamp.getTime(),\n localPeerId: this.localPeerId.truncate(),\n remotePeerId: this.remotePeerId.truncate(),\n });\n } else {\n if (DEBUG_PRINT_HEARTBEAT) {\n log('heartbeat RTT', {\n rtt: now - resp.requestTimestamp.getTime(),\n localPeerId: this.localPeerId.truncate(),\n remotePeerId: this.remotePeerId.truncate(),\n });\n }\n }\n }\n } catch (err: any) {\n const now = Date.now();\n if (err instanceof RpcClosedError) {\n // TODO: expose 'closed' event in Rpc peer to close context as soon the the peer gets closed\n log('ignoring RpcClosedError in heartbeat');\n this._extensionContext.close(err);\n return;\n }\n if (err instanceof AsyncTimeoutError) {\n log('timeout waiting for heartbeat response', { err, delay: now - reqTS.getTime() });\n this.opts.onTimeout(err);\n } else {\n log.info('other error waiting for heartbeat response', { err, delay: now - reqTS.getTime() });\n this.opts.onTimeout(err);\n }\n }\n },\n this.opts.heartbeatInterval,\n );\n }\n\n async onClose(err?: Error): Promise<void> {\n await this._ctx.dispose();\n await this._rpc.close();\n }\n\n async onAbort(err?: Error | undefined): Promise<void> {\n await this._ctx.dispose();\n await this._rpc.abort();\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Duplex } from 'node:stream';\n\nimport { Event } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { type RpcPort } from './rpc-port';\n\nconst FRAME_LENGTH_SIZE = 2;\n\n/**\n * Converts a stream of binary messages into a framed RpcPort.\n * Buffers are written prefixed by their length encoded as a varint.\n */\nexport class Framer {\n // private readonly _tagBuffer = Buffer.alloc(4)\n private _messageCb?: (msg: Uint8Array) => void = undefined;\n private _subscribeCb?: () => void = undefined;\n private _buffer?: Buffer = undefined; // The rest of the bytes from the previous write call.\n private _sendCallbacks: (() => void)[] = [];\n\n private _bytesSent = 0;\n private _bytesReceived = 0;\n\n private _writable = true;\n\n readonly drain = new Event();\n\n // TODO(egorgripasov): Consider using a Transform stream if it provides better backpressure handling.\n private readonly _stream = new Duplex({\n objectMode: false,\n read: () => {\n this._processResponseQueue();\n },\n write: (chunk, encoding, callback) => {\n invariant(!this._subscribeCb, 'Internal Framer bug. Concurrent writes detected.');\n\n this._bytesReceived += chunk.length;\n\n if (this._buffer && this._buffer.length > 0) {\n this._buffer = Buffer.concat([this._buffer, chunk]);\n } else {\n this._buffer = chunk;\n }\n\n if (this._messageCb) {\n this._popFrames();\n callback();\n } else {\n this._subscribeCb = () => {\n // Schedule the processing of the chunk after the peer subscribes to the messages.\n this._popFrames();\n this._subscribeCb = undefined;\n callback();\n };\n }\n },\n });\n\n public readonly port: RpcPort = {\n send: (message) => {\n // log('write', { len: message.length, frame: Buffer.from(message).toString('hex') })\n return new Promise<void>((resolve) => {\n const frame = encodeFrame(message);\n this._bytesSent += frame.length;\n this._writable = this._stream.push(frame);\n if (!this._writable) {\n this._sendCallbacks.push(resolve);\n } else {\n resolve();\n }\n });\n },\n subscribe: (callback) => {\n invariant(!this._messageCb, 'Rpc port already has a message listener.');\n this._messageCb = callback;\n this._subscribeCb?.();\n return () => {\n this._messageCb = undefined;\n };\n },\n };\n\n get stream(): Duplex {\n return this._stream;\n }\n\n get bytesSent() {\n return this._bytesSent;\n }\n\n get bytesReceived() {\n return this._bytesReceived;\n }\n\n get writable() {\n return this._writable;\n }\n\n private _processResponseQueue() {\n const responseQueue = this._sendCallbacks;\n this._sendCallbacks = [];\n this._writable = true;\n this.drain.emit();\n responseQueue.forEach((cb) => cb());\n }\n\n /**\n * Attempts to pop frames from the buffer and call the message callback.\n */\n private _popFrames() {\n let offset = 0;\n while (offset < this._buffer!.length) {\n const frame = decodeFrame(this._buffer!, offset);\n\n if (!frame) {\n break; // Couldn't read frame but there are still bytes left in the buffer.\n }\n offset += frame.bytesConsumed;\n // TODO(dmaretskyi): Possible bug if the peer unsubscribes while we're reading frames.\n // log('read', { len: frame.payload.length, frame: Buffer.from(frame.payload).toString('hex') })\n this._messageCb!(frame.payload);\n }\n\n if (offset < this._buffer!.length) {\n // Save the rest of the bytes for the next write call.\n this._buffer = this._buffer!.subarray(offset);\n } else {\n this._buffer = undefined;\n }\n }\n\n destroy() {\n // TODO(dmaretskyi): Call stream.end() instead?\n if (this._stream.readableLength > 0) {\n log('framer destroyed while there are still read bytes in the buffer.');\n }\n if (this._stream.writableLength > 0) {\n log.warn('framer destroyed while there are still write bytes in the buffer.');\n }\n this._stream.destroy();\n }\n}\n\n/**\n * Attempts to read a frame from the input buffer.\n */\nexport const decodeFrame = (buffer: Buffer, offset: number): { payload: Buffer; bytesConsumed: number } | undefined => {\n if (buffer.length < offset + FRAME_LENGTH_SIZE) {\n // Not enough bytes to read the frame length.\n return undefined;\n }\n\n const frameLength = buffer.readUInt16BE(offset);\n const bytesConsumed = FRAME_LENGTH_SIZE + frameLength;\n\n if (buffer.length < offset + bytesConsumed) {\n // Not enough bytes to read the frame.\n return undefined;\n }\n\n const payload = buffer.subarray(offset + FRAME_LENGTH_SIZE, offset + bytesConsumed);\n\n return {\n payload,\n bytesConsumed,\n };\n};\n\nexport const encodeFrame = (payload: Uint8Array): Buffer => {\n const frame = Buffer.allocUnsafe(FRAME_LENGTH_SIZE + payload.length);\n frame.writeUInt16BE(payload.length, 0);\n frame.set(payload, FRAME_LENGTH_SIZE);\n return frame;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Duplex } from 'node:stream';\n\nimport { scheduleTaskInterval, Event, Trigger, asyncTimeout } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { failUndefined } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\nimport { log, logInfo } from '@dxos/log';\nimport { schema, TimeoutError } from '@dxos/protocols';\nimport { type ConnectionInfo } from '@dxos/protocols/proto/dxos/devtools/swarm';\nimport { type Command } from '@dxos/protocols/proto/dxos/mesh/muxer';\n\nimport { Balancer } from './balancer';\nimport { type RpcPort } from './rpc-port';\n\nconst Command = schema.getCodecForType('dxos.mesh.muxer.Command');\n\nconst DEFAULT_SEND_COMMAND_TIMEOUT = 60_000;\nconst DESTROY_COMMAND_SEND_TIMEOUT = 5_000;\n\nexport type CleanupCb = void | (() => void);\n\nexport type CreateChannelOpts = {\n /**\n * MIME type of the wire content.\n *\n * Examples:\n * - application/octet-stream\n * - application/x-protobuf; messageType=\"dxos.rpc.Message\"\n */\n contentType?: string;\n};\n\nexport type MuxerStats = {\n timestamp: number;\n channels: ConnectionInfo.StreamStats[];\n bytesSent: number;\n bytesReceived: number;\n bytesSentRate?: number;\n bytesReceivedRate?: number;\n readBufferSize?: number;\n writeBufferSize?: number;\n};\n\nconst STATS_INTERVAL = 1_000;\nconst MAX_SAFE_FRAME_SIZE = 1_000_000;\nconst SYSTEM_CHANNEL_ID = 0;\nconst GRACEFUL_CLOSE_TIMEOUT = 3_000;\n\ntype Channel = {\n /**\n * Our local channel ID.\n * Incoming Data commands will have this ID.\n */\n id: number;\n tag: string;\n\n /**\n * Remote id is set when we receive an OpenChannel command.\n * The originating Data commands should carry this id.\n */\n remoteId: null | number;\n\n contentType?: string;\n\n /**\n * Send buffer.\n */\n buffer: Uint8Array[];\n\n /**\n * Set when we initialize a NodeJS stream or an RPC port consuming the channel.\n */\n push: null | ((data: Uint8Array) => void);\n\n destroy: null | ((err?: Error) => void);\n\n stats: {\n bytesSent: number;\n bytesReceived: number;\n };\n};\n\ntype CreateChannelInternalParams = {\n tag: string;\n contentType?: string;\n};\n\n/**\n * Channel based multiplexer.\n *\n * Can be used to open a number of channels represented by streams or RPC ports.\n * Performs framing for RPC ports.\n * Will buffer data until the remote peer opens the channel.\n *\n * The API will not advertise channels that as they are opened by the remote peer.\n * A higher level API (could be build on top of this muxer) for channel discovery is required.\n */\nexport class Muxer {\n private readonly _balancer = new Balancer(SYSTEM_CHANNEL_ID);\n private readonly _channelsByLocalId = new Map<number, Channel>();\n private readonly _channelsByTag = new Map<string, Channel>();\n private readonly _ctx = new Context();\n private _sessionId?: PublicKey;\n\n private _nextId = 1;\n\n private _closing = false;\n private _destroying = false;\n private _disposed = false;\n\n private _lastStats?: MuxerStats = undefined;\n private readonly _lastChannelStats = new Map<number, Channel['stats']>();\n\n public afterClosed = new Event<Error | undefined>();\n public statsUpdated = new Event<MuxerStats>();\n\n public readonly stream = this._balancer.stream;\n\n constructor() {\n // Add a channel for control messages.\n this._balancer.incomingData.on(async (msg) => {\n await this._handleCommand(Command.decode(msg));\n });\n }\n\n setSessionId(sessionId: PublicKey) {\n this._sessionId = sessionId;\n }\n\n @logInfo\n get sessionIdString(): string {\n return this._sessionId ? this._sessionId.truncate() : 'none';\n }\n\n /**\n * Creates a duplex Node.js-style stream.\n * The remote peer is expected to call `createStream` with the same tag.\n * The stream is immediately readable and writable.\n * NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).\n */\n async createStream(tag: string, opts: CreateChannelOpts = {}): Promise<Duplex> {\n const channel = this._getOrCreateStream({\n tag,\n contentType: opts.contentType,\n });\n invariant(!channel.push, `Channel already open: ${tag}`);\n\n const stream = new Duplex({\n write: (data, encoding, callback) => {\n this._sendData(channel, data)\n .then(() => callback())\n .catch(callback);\n // TODO(dmaretskyi): Should we error if sending data has errored?\n },\n read: () => {}, // No-op. We will push data when we receive it.\n });\n\n channel.push = (data) => {\n channel.stats.bytesReceived += data.length;\n stream.push(data);\n };\n channel.destroy = (err) => {\n // TODO(dmaretskyi): Call stream.end() instead?\n if (err) {\n if (stream.listeners('error').length > 0) {\n stream.destroy(err);\n } else {\n stream.destroy();\n }\n } else {\n stream.destroy();\n }\n };\n\n // NOTE: Make sure channel.push is set before sending the command.\n try {\n await this._sendCommand(\n {\n openChannel: {\n id: channel.id,\n tag: channel.tag,\n contentType: channel.contentType,\n },\n },\n SYSTEM_CHANNEL_ID,\n );\n } catch (err: any) {\n this._destroyChannel(channel, err);\n throw err;\n }\n\n return stream;\n }\n\n /**\n * Creates an RPC port.\n * The remote peer is expected to call `createPort` with the same tag.\n * The port is immediately usable.\n * NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).\n */\n async createPort(tag: string, opts: CreateChannelOpts = {}): Promise<RpcPort> {\n const channel = this._getOrCreateStream({\n tag,\n contentType: opts.contentType,\n });\n invariant(!channel.push, `Channel already open: ${tag}`);\n\n // We need to buffer incoming data until the port is subscribed to.\n let inboundBuffer: Uint8Array[] = [];\n let callback: ((data: Uint8Array) => void) | undefined;\n\n channel.push = (data) => {\n channel.stats.bytesReceived += data.length;\n if (callback) {\n callback(data);\n } else {\n inboundBuffer.push(data);\n }\n };\n\n const port: RpcPort = {\n send: async (data: Uint8Array, timeout?: number) => {\n await this._sendData(channel, data, timeout);\n // TODO(dmaretskyi): Debugging.\n // appendFileSync('log.json', JSON.stringify(schema.getCodecForType('dxos.rpc.RpcMessage').decode(data), null, 2) + '\\n')\n },\n subscribe: (cb: (data: Uint8Array) => void) => {\n invariant(!callback, 'Only one subscriber is allowed');\n callback = cb;\n for (const data of inboundBuffer) {\n cb(data);\n }\n inboundBuffer = [];\n },\n };\n\n // NOTE: Make sure channel.push is set before sending the command.\n try {\n await this._sendCommand(\n {\n openChannel: {\n id: channel.id,\n tag: channel.tag,\n contentType: channel.contentType,\n },\n },\n SYSTEM_CHANNEL_ID,\n );\n } catch (err: any) {\n this._destroyChannel(channel, err);\n throw err;\n }\n\n return port;\n }\n\n // initiate graceful close\n\n async close(err?: Error) {\n if (this._destroying) {\n log('already destroying, ignoring graceful close request');\n return;\n }\n if (this._closing) {\n log('already closing, ignoring graceful close request');\n return;\n }\n\n this._closing = true;\n\n await this._sendCommand(\n {\n close: {\n error: err?.message,\n },\n },\n SYSTEM_CHANNEL_ID,\n DESTROY_COMMAND_SEND_TIMEOUT,\n ).catch(async (err: any) => {\n log('error sending close command', { err });\n\n await this._dispose(err);\n });\n\n // don't return until close is complete or timeout\n await asyncTimeout(this._dispose(err), GRACEFUL_CLOSE_TIMEOUT, new TimeoutError('gracefully closing muxer'));\n }\n\n // force close without confirmation\n\n async destroy(err?: Error) {\n if (this._destroying) {\n log('already destroying, ignoring destroy request');\n return;\n }\n this._destroying = true;\n void this._ctx.dispose();\n if (this._closing) {\n log('destroy cancelling graceful close');\n this._closing = false;\n } else {\n // as a courtesy to the peer, send destroy command but ignore errors sending\n\n await this._sendCommand(\n {\n close: {\n error: err?.message,\n },\n },\n SYSTEM_CHANNEL_ID,\n ).catch(async (err: any) => {\n log('error sending courtesy close command', { err });\n });\n }\n\n this._dispose(err).catch((err) => {\n log('error disposing after destroy', { err });\n });\n }\n\n // complete the termination, graceful or otherwise\n\n async _dispose(err?: Error) {\n if (this._disposed) {\n log('already destroyed, ignoring dispose request');\n return;\n }\n\n void this._ctx.dispose();\n\n await this._balancer.destroy();\n\n for (const channel of this._channelsByTag.values()) {\n channel.destroy?.(err);\n }\n this._disposed = true;\n await this._emitStats();\n\n this.afterClosed.emit(err);\n\n // Make it easy for GC.\n this._channelsByLocalId.clear();\n this._channelsByTag.clear();\n }\n\n private async _handleCommand(cmd: Command) {\n if (this._disposed) {\n log.warn('Received command after disposed', { cmd });\n return;\n }\n\n if (cmd.close) {\n if (!this._closing) {\n log('received peer close, initiating my own graceful close');\n await this.close(new Error('received peer close'));\n } else {\n log('received close from peer, already closing');\n }\n\n return;\n }\n\n if (cmd.openChannel) {\n const channel = this._getOrCreateStream({\n tag: cmd.openChannel.tag,\n contentType: cmd.openChannel.contentType,\n });\n channel.remoteId = cmd.openChannel.id;\n\n // Flush any buffered data.\n for (const data of channel.buffer) {\n await this._sendCommand(\n {\n data: {\n channelId: channel.remoteId!,\n data,\n },\n },\n channel.id,\n );\n }\n channel.buffer = [];\n } else if (cmd.data) {\n const stream = this._channelsByLocalId.get(cmd.data.channelId) ?? failUndefined();\n if (!stream.push) {\n log.warn('Received data for channel before it was opened', { tag: stream.tag });\n return;\n }\n stream.push(cmd.data.data);\n }\n }\n\n private async _sendCommand(cmd: Command, channelId = -1, timeout = DEFAULT_SEND_COMMAND_TIMEOUT) {\n if (this._disposed) {\n // log.info('ignoring sendCommand after disposed', { cmd });\n return;\n }\n try {\n const trigger = new Trigger<void>();\n this._balancer.pushData(Command.encode(cmd), trigger, channelId);\n await trigger.wait({ timeout });\n } catch (err: any) {\n await this.destroy(err);\n }\n }\n\n private _getOrCreateStream(params: CreateChannelInternalParams): Channel {\n if (this._channelsByTag.size === 0) {\n scheduleTaskInterval(this._ctx, async () => this._emitStats(), STATS_INTERVAL);\n }\n let channel = this._channelsByTag.get(params.tag);\n if (!channel) {\n channel = {\n id: this._nextId++,\n remoteId: null,\n tag: params.tag,\n contentType: params.contentType,\n buffer: [],\n push: null,\n destroy: null,\n stats: {\n bytesSent: 0,\n bytesReceived: 0,\n },\n };\n this._channelsByTag.set(channel.tag, channel);\n this._channelsByLocalId.set(channel.id, channel);\n this._balancer.addChannel(channel.id);\n }\n\n return channel;\n }\n\n private async _sendData(channel: Channel, data: Uint8Array, timeout?: number): Promise<void> {\n if (data.length > MAX_SAFE_FRAME_SIZE) {\n log.warn('frame size exceeds maximum safe value', { size: data.length, threshold: MAX_SAFE_FRAME_SIZE });\n }\n\n channel.stats.bytesSent += data.length;\n if (channel.remoteId === null) {\n // Remote side has not opened the channel yet.\n channel.buffer.push(data);\n return;\n }\n await this._sendCommand(\n {\n data: {\n channelId: channel.remoteId,\n data,\n },\n },\n channel.id,\n timeout,\n );\n }\n\n private _destroyChannel(channel: Channel, err?: Error) {\n if (channel.destroy) {\n channel.destroy(err);\n }\n\n this._channelsByLocalId.delete(channel.id);\n this._channelsByTag.delete(channel.tag);\n }\n\n private async _emitStats() {\n if (this._disposed || this._destroying) {\n if (!this._lastStats) {\n return;\n }\n\n // zero out counting stats to not skew metrics.\n const lastStats = this._lastStats;\n this._lastStats = undefined;\n\n lastStats.readBufferSize = 0;\n lastStats.writeBufferSize = 0;\n for (const c of lastStats.channels) {\n c.writeBufferSize = 0;\n }\n this.statsUpdated.emit(lastStats);\n\n this._lastChannelStats.clear();\n return;\n }\n\n const bytesSent = this._balancer.bytesSent;\n const bytesReceived = this._balancer.bytesReceived;\n\n const now = Date.now();\n const interval = this._lastStats ? (now - this._lastStats.timestamp) / 1_000 : 0;\n const calculateThroughput = (current: Channel['stats'], last: Channel['stats'] | undefined) =>\n last\n ? {\n bytesSentRate: interval ? (current.bytesSent - last.bytesSent) / interval : undefined,\n bytesReceivedRate: interval ? (current.bytesReceived - last.bytesReceived) / interval : undefined,\n }\n : {};\n\n this._lastStats = {\n timestamp: now,\n channels: Array.from(this._channelsByTag.values()).map((channel) => {\n const stats: ConnectionInfo.StreamStats = {\n id: channel.id,\n tag: channel.tag,\n contentType: channel.contentType,\n writeBufferSize: channel.buffer.length,\n bytesSent: channel.stats.bytesSent,\n bytesReceived: channel.stats.bytesReceived,\n ...calculateThroughput(channel.stats, this._lastChannelStats.get(channel.id)),\n };\n\n this._lastChannelStats.set(channel.id, stats);\n return stats;\n }),\n bytesSent,\n bytesReceived,\n ...calculateThroughput({ bytesSent, bytesReceived }, this._lastStats),\n readBufferSize: this._balancer.stream.readableLength,\n writeBufferSize: this._balancer.stream.writableLength,\n };\n\n this.statsUpdated.emit(this._lastStats);\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport * as varint from 'varint';\n\nimport { type Trigger, Event } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\n\nimport { Framer } from './framer';\n\nconst MAX_CHUNK_SIZE = 8192;\n\ntype Chunk = {\n chunk: Uint8Array;\n channelId: number;\n dataLength?: number;\n};\n\ntype ChunkEnvelope = {\n msg: Buffer;\n trigger?: Trigger;\n};\n\ntype ChannelBuffer = {\n buffer: Buffer;\n msgLength: number;\n};\n\n/**\n * Load balancer for handling asynchronous calls from multiple channels.\n *\n * Manages a queue of calls from different channels and ensures that the calls\n * are processed in a balanced manner in a round-robin fashion.\n */\nexport class Balancer {\n private _lastCallerIndex = 0;\n private _channels: number[] = [];\n\n private readonly _framer = new Framer();\n // TODO(egorgripasov): Will cause a memory leak if channels do not appreciate the backpressure.\n private readonly _sendBuffers: Map<number, ChunkEnvelope[]> = new Map();\n private readonly _receiveBuffers = new Map<number, ChannelBuffer>();\n\n private _sending = false;\n public incomingData = new Event<Uint8Array>();\n public readonly stream = this._framer.stream;\n\n constructor(private readonly _sysChannelId: number) {\n this._channels.push(_sysChannelId);\n\n // Handle incoming messages.\n this._framer.port.subscribe(this._processIncomingMessage.bind(this));\n }\n\n get bytesSent() {\n return this._framer.bytesSent;\n }\n\n get bytesReceived() {\n return this._framer.bytesReceived;\n }\n\n get buffersCount() {\n return this._sendBuffers.size;\n }\n\n addChannel(channel: number) {\n this._channels.push(channel);\n }\n\n pushData(data: Uint8Array, trigger: Trigger, channelId: number) {\n this._enqueueChunk(data, trigger, channelId);\n this._sendChunks().catch((err) => log.catch(err));\n }\n\n destroy() {\n if (this._sendBuffers.size !== 0) {\n log.info('destroying balancer with pending calls');\n }\n this._sendBuffers.clear();\n this._framer.destroy();\n }\n\n private _processIncomingMessage(msg: Uint8Array) {\n const { channelId, dataLength, chunk } = decodeChunk(msg, (channelId) => !this._receiveBuffers.has(channelId));\n if (!this._receiveBuffers.has(channelId)) {\n if (chunk.length < dataLength!) {\n this._receiveBuffers.set(channelId, {\n buffer: Buffer.from(chunk),\n msgLength: dataLength!,\n });\n } else {\n this.incomingData.emit(chunk);\n }\n } else {\n const channelBuffer = this._receiveBuffers.get(channelId)!;\n channelBuffer.buffer = Buffer.concat([channelBuffer.buffer, chunk]);\n if (channelBuffer.buffer.length < channelBuffer.msgLength) {\n return;\n }\n const msg = channelBuffer.buffer;\n this._receiveBuffers.delete(channelId);\n this.incomingData.emit(msg);\n }\n }\n\n private _getNextCallerId() {\n if (this._sendBuffers.has(this._sysChannelId)) {\n return this._sysChannelId;\n }\n\n const index = this._lastCallerIndex;\n this._lastCallerIndex = (this._lastCallerIndex + 1) % this._channels.length;\n\n return this._channels[index];\n }\n\n private _enqueueChunk(data: Uint8Array, trigger: Trigger, channelId: number) {\n if (!this._channels.includes(channelId)) {\n throw new Error(`Unknown channel ${channelId}`);\n }\n\n if (!this._sendBuffers.has(channelId)) {\n this._sendBuffers.set(channelId, []);\n }\n\n const sendBuffer = this._sendBuffers.get(channelId)!;\n\n const chunks = [];\n for (let idx = 0; idx < data.length; idx += MAX_CHUNK_SIZE) {\n chunks.push(data.subarray(idx, idx + MAX_CHUNK_SIZE));\n }\n\n chunks.forEach((chunk, index) => {\n const msg = encodeChunk({\n chunk,\n channelId,\n dataLength: index === 0 ? data.length : undefined,\n });\n sendBuffer.push({ msg, trigger: index === chunks.length - 1 ? trigger : undefined });\n });\n }\n\n // get the next chunk or null if there are no chunks remaining\n\n private _getNextChunk(): ChunkEnvelope | null {\n let chunk;\n while (this._sendBuffers.size > 0) {\n const channelId = this._getNextCallerId();\n const sendBuffer = this._sendBuffers.get(channelId);\n if (!sendBuffer) {\n continue;\n }\n\n chunk = sendBuffer.shift();\n if (!chunk) {\n continue;\n }\n if (sendBuffer.length === 0) {\n this._sendBuffers.delete(channelId);\n }\n return chunk;\n }\n return null;\n }\n\n private async _sendChunks() {\n if (this._sending) {\n return;\n }\n this._sending = true;\n let chunk: ChunkEnvelope | null;\n chunk = this._getNextChunk();\n while (chunk) {\n // TODO(nf): determine whether this is needed since we await the chunk send\n if (!this._framer.writable) {\n log('PAUSE for drain');\n await this._framer.drain.waitForCount(1);\n log('RESUME for drain');\n }\n try {\n await this._framer.port.send(chunk.msg);\n chunk.trigger?.wake();\n } catch (err: any) {\n log('Error sending chunk', { err });\n chunk.trigger?.throw(err);\n }\n chunk = this._getNextChunk();\n }\n invariant(this._sendBuffers.size === 0, 'sendBuffers not empty');\n this._sending = false;\n }\n}\n\nexport const encodeChunk = ({ channelId, dataLength, chunk }: Chunk): Buffer => {\n const channelTagLength = varint.encodingLength(channelId);\n const dataLengthLength = dataLength ? varint.encodingLength(dataLength) : 0;\n const message = Buffer.allocUnsafe(channelTagLength + dataLengthLength + chunk.length);\n varint.encode(channelId, message);\n if (dataLength) {\n varint.encode(dataLength, message, channelTagLength);\n }\n message.set(chunk, channelTagLength + dataLengthLength);\n return message;\n};\n\nexport const decodeChunk = (data: Uint8Array, withLength: (channelId: number) => boolean): Chunk => {\n const channelId = varint.decode(data);\n let dataLength: number | undefined;\n let offset = varint.decode.bytes;\n\n if (withLength(channelId)) {\n dataLength = varint.decode(data, offset);\n offset += varint.decode.bytes;\n }\n\n const chunk = data.subarray(offset);\n\n return { channelId, dataLength, chunk };\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { asyncTimeout, Trigger } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { type TestService } from '@dxos/protocols/proto/example/testing/rpc';\nimport { createProtoRpcPeer, type ProtoRpcPeer } from '@dxos/rpc';\n\nimport { type ExtensionContext, type TeleportExtension } from '../teleport';\n\ninterface TestExtensionCallbacks {\n onOpen?: () => Promise<void>;\n onClose?: () => Promise<void>;\n onAbort?: () => Promise<void>;\n}\n\nexport class TestExtension implements TeleportExtension {\n public readonly open = new Trigger();\n public readonly closed = new Trigger();\n public readonly aborted = new Trigger();\n public extensionContext: ExtensionContext | undefined;\n private _rpc!: ProtoRpcPeer<{ TestService: TestService }>;\n\n constructor(public readonly callbacks: TestExtensionCallbacks = {}) {}\n\n get remotePeerId() {\n return this.extensionContext?.remotePeerId;\n }\n\n async onOpen(context: ExtensionContext) {\n log('onOpen', { localPeerId: context.localPeerId, remotePeerId: context.remotePeerId });\n this.extensionContext = context;\n this._rpc = createProtoRpcPeer<{ TestService: TestService }, { TestService: TestService }>({\n port: await context.createPort('rpc', {\n contentType: 'application/x-protobuf; messageType=\"dxos.rpc.Message\"',\n }),\n requested: {\n TestService: schema.getService('example.testing.rpc.TestService'),\n },\n exposed: {\n TestService: schema.getService('example.testing.rpc.TestService'),\n },\n handlers: {\n TestService: {\n voidCall: async (request) => {\n // Ok.\n },\n testCall: async (request) => {\n return {\n data: request.data,\n };\n },\n },\n },\n timeout: 2000,\n });\n\n await this._rpc.open();\n await this.callbacks.onOpen?.();\n\n this.open.wake();\n }\n\n async onClose(err?: Error) {\n log('onClose', { err });\n await this.callbacks.onClose?.();\n this.closed.wake();\n await this._rpc?.close();\n }\n\n async onAbort(err?: Error) {\n log('onAbort', { err });\n await this.callbacks.onAbort?.();\n this.aborted.wake();\n await this._rpc?.abort();\n }\n\n async test(message = 'test') {\n await this.open.wait({ timeout: 1500 });\n const res = await asyncTimeout(this._rpc.rpc.TestService.testCall({ data: message }), 1500);\n invariant(res.data === message);\n }\n\n /**\n * Force-close the connection.\n */\n async closeConnection(err?: Error) {\n this.extensionContext?.close(err);\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { randomBytes } from 'node:crypto';\nimport { type Duplex } from 'node:stream';\n\nimport { Trigger } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { type TestServiceWithStreams } from '@dxos/protocols/proto/example/testing/rpc';\nimport { createProtoRpcPeer, type ProtoRpcPeer } from '@dxos/rpc';\n\nimport { type ExtensionContext, type TeleportExtension } from '../teleport';\n\ninterface TestExtensionWithStreamsCallbacks {\n onOpen?: () => Promise<void>;\n onClose?: () => Promise<void>;\n onAbort?: () => Promise<void>;\n}\n\nexport class TestExtensionWithStreams implements TeleportExtension {\n public readonly open = new Trigger();\n public readonly closed = new Trigger();\n public readonly aborted = new Trigger();\n private readonly _streams = new Map<string, TestStream>();\n\n public extensionContext: ExtensionContext | undefined;\n private _rpc!: ProtoRpcPeer<{ TestServiceWithStreams: TestServiceWithStreams }>;\n\n constructor(public readonly callbacks: TestExtensionWithStreamsCallbacks = {}) {}\n\n get remotePeerId() {\n return this.extensionContext?.remotePeerId;\n }\n\n private async _openStream(streamTag: string, interval = 5, chunkSize = 2048) {\n invariant(!this._streams.has(streamTag), `Stream already exists: ${streamTag}`);\n\n const networkStream = await this.extensionContext!.createStream(streamTag, {\n contentType: 'application/x-test-stream',\n });\n\n const streamEntry: TestStream = {\n networkStream,\n bytesSent: 0,\n bytesReceived: 0,\n sendErrors: 0,\n receiveErrors: 0,\n startTimestamp: Date.now(),\n };\n\n const pushChunk = () => {\n streamEntry.timer = setTimeout(() => {\n const chunk = randomBytes(chunkSize);\n\n if (\n !networkStream.write(chunk, 'binary', (err) => {\n if (!err) {\n streamEntry.bytesSent += chunk.length;\n } else {\n streamEntry.sendErrors += 1;\n }\n })\n ) {\n networkStream.once('drain', pushChunk);\n } else {\n process.nextTick(pushChunk);\n }\n }, interval);\n };\n\n pushChunk();\n\n this._streams.set(streamTag, streamEntry);\n\n networkStream.on('data', (data) => {\n streamEntry.bytesReceived += data.length;\n });\n\n networkStream.on('error', (err) => {\n streamEntry.receiveErrors += 1;\n });\n\n networkStream.on('close', () => {\n networkStream.removeAllListeners();\n });\n\n streamEntry.reportingTimer = setInterval(() => {\n const { bytesSent, bytesReceived, sendErrors, receiveErrors } = streamEntry;\n // log.info('stream stats', { streamTag, bytesSent, bytesReceived, sendErrors, receiveErrors });\n log.trace('dxos.test.stream-stats', {\n streamTag,\n bytesSent,\n bytesReceived,\n sendErrors,\n receiveErrors,\n from: this.extensionContext?.localPeerId,\n to: this.extensionContext?.remotePeerId,\n });\n }, 100);\n }\n\n private _closeStream(streamTag: string): Stats {\n invariant(this._streams.has(streamTag), `Stream does not exist: ${streamTag}`);\n\n const stream = this._streams.get(streamTag)!;\n\n clearTimeout(stream.timer);\n clearTimeout(stream.reportingTimer);\n\n const { bytesSent, bytesReceived, sendErrors, receiveErrors, startTimestamp } = stream;\n\n stream.networkStream.destroy();\n this._streams.delete(streamTag);\n\n return {\n bytesSent,\n bytesReceived,\n sendErrors,\n receiveErrors,\n runningTime: Date.now() - (startTimestamp ?? 0),\n };\n }\n\n async onOpen(context: ExtensionContext) {\n log('onOpen', { localPeerId: context.localPeerId, remotePeerId: context.remotePeerId });\n this.extensionContext = context;\n this._rpc = createProtoRpcPeer<\n { TestServiceWithStreams: TestServiceWithStreams },\n { TestServiceWithStreams: TestServiceWithStreams }\n >({\n port: await context.createPort('rpc', {\n contentType: 'application/x-protobuf; messageType=\"dxos.rpc.Message\"',\n }),\n requested: {\n TestServiceWithStreams: schema.getService('example.testing.rpc.TestServiceWithStreams'),\n },\n exposed: {\n TestServiceWithStreams: schema.getService('example.testing.rpc.TestServiceWithStreams'),\n },\n handlers: {\n TestServiceWithStreams: {\n requestTestStream: async (request) => {\n const { data: streamTag, streamLoadInterval, streamLoadChunkSize } = request;\n\n await this._openStream(streamTag, streamLoadInterval, streamLoadChunkSize);\n\n return {\n data: streamTag,\n };\n },\n closeTestStream: async (request) => {\n const streamTag = request.data;\n const { bytesSent, bytesReceived, sendErrors, receiveErrors, runningTime } = this._closeStream(streamTag);\n\n return {\n data: streamTag,\n bytesSent,\n bytesReceived,\n sendErrors,\n receiveErrors,\n runningTime,\n };\n },\n },\n },\n timeout: 2000,\n });\n\n await this._rpc.open();\n await this.callbacks.onOpen?.();\n\n this.open.wake();\n }\n\n async onClose(err?: Error) {\n log('onClose', { err });\n await this.callbacks.onClose?.();\n this.closed.wake();\n for (const [streamTag, stream] of Object.entries(this._streams)) {\n log('closing stream', { streamTag });\n clearTimeout(stream.interval);\n stream.networkStream.destroy();\n }\n await this._rpc?.close();\n }\n\n async onAbort(err?: Error) {\n log('onAbort', { err });\n await this.callbacks.onAbort?.();\n this.aborted.wake();\n await this._rpc?.abort();\n }\n\n async addNewStream(streamLoadInterval: number, streamLoadChunkSize: number, streamTag?: string): Promise<string> {\n await this.open.wait({ timeout: 1500 });\n if (!streamTag) {\n streamTag = `stream-${randomBytes(4).toString('hex')}`;\n }\n const { data } = await this._rpc.rpc.TestServiceWithStreams.requestTestStream({\n data: streamTag,\n streamLoadInterval,\n streamLoadChunkSize,\n });\n invariant(data === streamTag);\n\n await this._openStream(streamTag, streamLoadInterval, streamLoadChunkSize);\n return streamTag;\n }\n\n async closeStream(streamTag: string): Promise<TestStreamStats> {\n await this.open.wait({ timeout: 1500 });\n const { data, bytesSent, bytesReceived, sendErrors, receiveErrors, runningTime } =\n await this._rpc.rpc.TestServiceWithStreams.closeTestStream({\n data: streamTag,\n });\n\n invariant(data === streamTag);\n\n const local = this._closeStream(streamTag);\n\n return {\n streamTag,\n stats: {\n local,\n remote: {\n bytesSent,\n bytesReceived,\n sendErrors,\n receiveErrors,\n runningTime,\n },\n },\n };\n }\n\n /**\n * Force-close the connection.\n */\n async closeConnection(err?: Error) {\n this.extensionContext?.close(err);\n }\n}\n\ntype Stats = {\n bytesSent: number;\n bytesReceived: number;\n sendErrors: number;\n receiveErrors: number;\n runningTime: number;\n};\n\nexport type TestStreamStats = {\n streamTag: string;\n stats: {\n local: Stats;\n remote: Stats;\n };\n};\n\ntype TestStream = {\n networkStream: Duplex;\n bytesSent: number;\n bytesReceived: number;\n sendErrors: number;\n receiveErrors: number;\n timer?: NodeJS.Timer;\n startTimestamp?: number;\n reportingTimer?: NodeJS.Timer;\n};\n"],
|
5
|
+
"mappings": ";;;;;;;;;;AAIA,SAAsBA,gBAAgB;AAEtC,SAASC,wBAAwB;AACjC,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,OAAAA,YAAW;;;ACHpB,SAASC,mBAAmBC,cAAcC,oBAAgC;AAC1E,SAASC,WAAAA,gBAAe;AACxB,SAASC,iBAAAA,sBAAqB;AAC9B,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,iBAAiB;AAC1B,SAASC,OAAAA,MAAKC,WAAAA,gBAAe;AAC7B,SAASC,kBAAAA,iBAAgBC,gBAAAA,qBAAoB;;;ACR7C,SAASC,cAAcC,sBAAsBC,gBAAgBC,yBAAyB;AACtF,SAASC,eAAe;AAExB,SAASC,WAAW;AACpB,SAASC,QAAQC,sBAAsB;AAEvC,SAASC,0BAA6C;AACtD,SAASC,gBAAgB;;AAIzB,IAAMC,4BAA4B;AAClC,IAAMC,wBAAwB;AAYvB,IAAMC,mBAAN,MAAMA;EAYXC,YACmBC,MACAC,aACAC,cACjB;SAHiBF,OAAAA;SACAC,cAAAA;SACAC,eAAAA;SAdFC,OAAO,IAAIb,QAAQ;MAClCc,SAAS,CAACC,QAAAA;AACR,aAAKC,kBAAkBC,MAAMF,GAAAA;MAC/B;IACF,GAAA;;;;SAEgBG,wBAAwB,IAAIb,SAAAA;EASzC;EAEH,MAAMc,kBAAkBC,MAAc;AACpC,UAAM,KAAKC,KAAKC,IAAIC,QAAQJ,kBAAkB;MAAEC;IAAK,CAAA;EACvD;EAEA,MAAMI,OAAOC,kBAAmD;AAC9D,SAAKT,oBAAoBS;AAEzB,SAAKJ,OAAOjB,mBAAuD;MACjEsB,WAAW;QACTH,SAASrB,OAAOyB,WAAW,2CAAA;MAC7B;MACAC,SAAS;QACPL,SAASrB,OAAOyB,WAAW,2CAAA;MAC7B;MACAE,UAAU;QACRN,SAAS;UACPJ,mBAAmB,OAAOW,YAAAA;AACxB,iBAAKZ,sBAAsBa,KAAKD,QAAQV,IAAI;UAC9C;UACAY,WAAW,OAAOF,YAAAA;AAChB,gBAAIvB,uBAAuB;AACzBN,kBAAI,8BAA8B;gBAChCgC,IAAIH,QAAQI;gBACZvB,aAAa,KAAKA,YAAYwB,SAAQ;gBACtCvB,cAAc,KAAKA,aAAauB,SAAQ;cAC1C,GAAA;;;;;;YACF;AACA,mBAAO;cACLD,kBAAkBJ,QAAQI;YAC5B;UACF;QACF;MACF;MACAE,MAAM,MAAMX,iBAAiBY,WAAW,OAAO;QAC7CC,aAAa;MACf,CAAA;MACAC,SAAS,KAAK7B,KAAK8B;IACrB,CAAA;AAEA,UAAM,KAAKnB,KAAKoB,KAAI;AAEpB5C,yBACE,KAAKgB,MACL,YAAA;AACE,YAAM6B,QAAQ,oBAAIC,KAAAA;AAClB,UAAI;AACF,cAAMC,OAAO,MAAMhD,aACjB,KAAKyB,KAAKC,IAAIC,QAAQS,UAAU;UAAEE,kBAAkBQ;QAAM,CAAA,GAC1D,KAAKhC,KAAK8B,gBAAgB;AAE5B,cAAMK,MAAMF,KAAKE,IAAG;AAEpB,YAAID,KAAKV,4BAA4BS,MAAM;AACzC,cACEE,MAAMD,KAAKV,iBAAiBY,QAAO,KAClCxC,4BAA4B,KAAKI,KAAK8B,mBACnClC,4BACA,KAAKI,KAAK8B,mBAAmB,IACjC;AACAvC,gBAAI8C,KAAK,gCAAgCzC,4BAA4B,GAAA,KAAS;cAC5E0C,KAAKH,MAAMD,KAAKV,iBAAiBY,QAAO;cACxCnC,aAAa,KAAKA,YAAYwB,SAAQ;cACtCvB,cAAc,KAAKA,aAAauB,SAAQ;YAC1C,GAAA;;;;;;UACF,OAAO;AACL,gBAAI5B,uBAAuB;AACzBN,kBAAI,iBAAiB;gBACnB+C,KAAKH,MAAMD,KAAKV,iBAAiBY,QAAO;gBACxCnC,aAAa,KAAKA,YAAYwB,SAAQ;gBACtCvB,cAAc,KAAKA,aAAauB,SAAQ;cAC1C,GAAA;;;;;;YACF;UACF;QACF;MACF,SAASpB,KAAU;AACjB,cAAM8B,MAAMF,KAAKE,IAAG;AACpB,YAAI9B,eAAeZ,gBAAgB;AAEjCF,cAAI,wCAAA,QAAA;;;;;;AACJ,eAAKe,kBAAkBC,MAAMF,GAAAA;AAC7B;QACF;AACA,YAAIA,eAAehB,mBAAmB;AACpCE,cAAI,0CAA0C;YAAEc;YAAKkC,OAAOJ,MAAMH,MAAMI,QAAO;UAAG,GAAA;;;;;;AAClF,eAAKpC,KAAKwC,UAAUnC,GAAAA;QACtB,OAAO;AACLd,cAAIkD,KAAK,8CAA8C;YAAEpC;YAAKkC,OAAOJ,MAAMH,MAAMI,QAAO;UAAG,GAAA;;;;;;AAC3F,eAAKpC,KAAKwC,UAAUnC,GAAAA;QACtB;MACF;IACF,GACA,KAAKL,KAAK0C,iBAAiB;EAE/B;EAEA,MAAMC,QAAQtC,KAA4B;AACxC,UAAM,KAAKF,KAAKyC,QAAO;AACvB,UAAM,KAAKjC,KAAKJ,MAAK;EACvB;EAEA,MAAMsC,QAAQxC,KAAwC;AACpD,UAAM,KAAKF,KAAKyC,QAAO;AACvB,UAAM,KAAKjC,KAAKmC,MAAK;EACvB;AACF;;;AClJA,SAASC,cAAc;AAEvB,SAASC,aAAa;AACtB,SAASC,iBAAiB;AAC1B,SAASC,OAAAA,YAAW;;AAIpB,IAAMC,oBAAoB;AAMnB,IAAMC,SAAN,MAAMA;EAAN;AAEGC;sBAAyCC;AACzCC,wBAA4BD;AAC5BE,mBAAmBF;AACnBG,0BAAiC,CAAA;AAEjCC,sBAAa;AACbC,0BAAiB;AAEjBC,qBAAY;AAEXC,iBAAQ,IAAIb,MAAAA;AAGJc;mBAAU,IAAIf,OAAO;MACpCgB,YAAY;MACZC,MAAM,MAAA;AACJ,aAAKC,sBAAqB;MAC5B;MACAC,OAAO,CAACC,OAAOC,UAAUC,aAAAA;AACvBpB,kBAAU,CAAC,KAAKM,cAAc,oDAAA;;;;;;;;;AAE9B,aAAKI,kBAAkBQ,MAAMG;AAE7B,YAAI,KAAKd,WAAW,KAAKA,QAAQc,SAAS,GAAG;AAC3C,eAAKd,UAAUe,OAAOC,OAAO;YAAC,KAAKhB;YAASW;WAAM;QACpD,OAAO;AACL,eAAKX,UAAUW;QACjB;AAEA,YAAI,KAAKd,YAAY;AACnB,eAAKoB,WAAU;AACfJ,mBAAAA;QACF,OAAO;AACL,eAAKd,eAAe,MAAA;AAElB,iBAAKkB,WAAU;AACf,iBAAKlB,eAAeD;AACpBe,qBAAAA;UACF;QACF;MACF;IACF,CAAA;AAEgBK,gBAAgB;MAC9BC,MAAM,CAACC,YAAAA;AAEL,eAAO,IAAIC,QAAc,CAACC,YAAAA;AACxB,gBAAMC,QAAQC,YAAYJ,OAAAA;AAC1B,eAAKlB,cAAcqB,MAAMT;AACzB,eAAKV,YAAY,KAAKE,QAAQmB,KAAKF,KAAAA;AACnC,cAAI,CAAC,KAAKnB,WAAW;AACnB,iBAAKH,eAAewB,KAAKH,OAAAA;UAC3B,OAAO;AACLA,oBAAAA;UACF;QACF,CAAA;MACF;MACAI,WAAW,CAACb,aAAAA;AACVpB,kBAAU,CAAC,KAAKI,YAAY,4CAAA;;;;;;;;;AAC5B,aAAKA,aAAagB;AAClB,aAAKd,eAAY;AACjB,eAAO,MAAA;AACL,eAAKF,aAAaC;QACpB;MACF;IACF;;EAEA,IAAI6B,SAAiB;AACnB,WAAO,KAAKrB;EACd;EAEA,IAAIsB,YAAY;AACd,WAAO,KAAK1B;EACd;EAEA,IAAI2B,gBAAgB;AAClB,WAAO,KAAK1B;EACd;EAEA,IAAI2B,WAAW;AACb,WAAO,KAAK1B;EACd;EAEQK,wBAAwB;AAC9B,UAAMsB,gBAAgB,KAAK9B;AAC3B,SAAKA,iBAAiB,CAAA;AACtB,SAAKG,YAAY;AACjB,SAAKC,MAAM2B,KAAI;AACfD,kBAAcE,QAAQ,CAACC,OAAOA,GAAAA,CAAAA;EAChC;;;;EAKQjB,aAAa;AACnB,QAAIkB,SAAS;AACb,WAAOA,SAAS,KAAKnC,QAASc,QAAQ;AACpC,YAAMS,QAAQa,YAAY,KAAKpC,SAAUmC,MAAAA;AAEzC,UAAI,CAACZ,OAAO;AACV;MACF;AACAY,gBAAUZ,MAAMc;AAGhB,WAAKxC,WAAY0B,MAAMe,OAAO;IAChC;AAEA,QAAIH,SAAS,KAAKnC,QAASc,QAAQ;AAEjC,WAAKd,UAAU,KAAKA,QAASuC,SAASJ,MAAAA;IACxC,OAAO;AACL,WAAKnC,UAAUF;IACjB;EACF;EAEA0C,UAAU;AAER,QAAI,KAAKlC,QAAQmC,iBAAiB,GAAG;AACnC/C,MAAAA,KAAI,oEAAA,QAAA;;;;;;IACN;AACA,QAAI,KAAKY,QAAQoC,iBAAiB,GAAG;AACnChD,MAAAA,KAAIiD,KAAK,qEAAA,QAAA;;;;;;IACX;AACA,SAAKrC,QAAQkC,QAAO;EACtB;AACF;AAKO,IAAMJ,cAAc,CAACQ,QAAgBT,WAAAA;AAC1C,MAAIS,OAAO9B,SAASqB,SAASxC,mBAAmB;AAE9C,WAAOG;EACT;AAEA,QAAM+C,cAAcD,OAAOE,aAAaX,MAAAA;AACxC,QAAME,gBAAgB1C,oBAAoBkD;AAE1C,MAAID,OAAO9B,SAASqB,SAASE,eAAe;AAE1C,WAAOvC;EACT;AAEA,QAAMwC,UAAUM,OAAOL,SAASJ,SAASxC,mBAAmBwC,SAASE,aAAAA;AAErE,SAAO;IACLC;IACAD;EACF;AACF;AAEO,IAAMb,cAAc,CAACc,YAAAA;AAC1B,QAAMf,QAAQR,OAAOgC,YAAYpD,oBAAoB2C,QAAQxB,MAAM;AACnES,QAAMyB,cAAcV,QAAQxB,QAAQ,CAAA;AACpCS,QAAM0B,IAAIX,SAAS3C,iBAAAA;AACnB,SAAO4B;AACT;;;AC9KA,SAAS2B,UAAAA,eAAc;AAEvB,SAASC,wBAAAA,uBAAsBC,SAAAA,QAAOC,SAASC,gBAAAA,qBAAoB;AACnE,SAASC,WAAAA,gBAAe;AACxB,SAASC,qBAAqB;AAC9B,SAASC,aAAAA,kBAAiB;AAE1B,SAASC,OAAAA,MAAKC,eAAe;AAC7B,SAASC,UAAAA,SAAQC,oBAAoB;;;ACRrC,YAAYC,YAAY;AAExB,SAAuBC,SAAAA,cAAa;AACpC,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,OAAAA,YAAW;;AAIpB,IAAMC,iBAAiB;AAwBhB,IAAMC,WAAN,MAAMA;EAaXC,YAA6BC,eAAuB;SAAvBA,gBAAAA;SAZrBC,mBAAmB;SACnBC,YAAsB,CAAA;SAEbC,UAAU,IAAIC,OAAAA;SAEdC,eAA6C,oBAAIC,IAAAA;SACjDC,kBAAkB,oBAAID,IAAAA;SAE/BE,WAAW;SACZC,eAAe,IAAIC,OAAAA;SACVC,SAAS,KAAKR,QAAQQ;AAGpC,SAAKT,UAAUU,KAAKZ,aAAAA;AAGpB,SAAKG,QAAQU,KAAKC,UAAU,KAAKC,wBAAwBC,KAAK,IAAI,CAAA;EACpE;EAEA,IAAIC,YAAY;AACd,WAAO,KAAKd,QAAQc;EACtB;EAEA,IAAIC,gBAAgB;AAClB,WAAO,KAAKf,QAAQe;EACtB;EAEA,IAAIC,eAAe;AACjB,WAAO,KAAKd,aAAae;EAC3B;EAEAC,WAAWC,SAAiB;AAC1B,SAAKpB,UAAUU,KAAKU,OAAAA;EACtB;EAEAC,SAASC,MAAkBC,SAAkBC,WAAmB;AAC9D,SAAKC,cAAcH,MAAMC,SAASC,SAAAA;AAClC,SAAKE,YAAW,EAAGC,MAAM,CAACC,QAAQC,KAAIF,MAAMC,KAAAA,QAAAA;;;;;;EAC9C;EAEAE,UAAU;AACR,QAAI,KAAK3B,aAAae,SAAS,GAAG;AAChCW,MAAAA,KAAIE,KAAK,0CAAA,QAAA;;;;;;IACX;AACA,SAAK5B,aAAa6B,MAAK;AACvB,SAAK/B,QAAQ6B,QAAO;EACtB;EAEQjB,wBAAwBoB,KAAiB;AAC/C,UAAM,EAAET,WAAWU,YAAYC,MAAK,IAAKC,YAAYH,KAAK,CAACT,eAAc,CAAC,KAAKnB,gBAAgBgC,IAAIb,UAAAA,CAAAA;AACnG,QAAI,CAAC,KAAKnB,gBAAgBgC,IAAIb,SAAAA,GAAY;AACxC,UAAIW,MAAMG,SAASJ,YAAa;AAC9B,aAAK7B,gBAAgBkC,IAAIf,WAAW;UAClCgB,QAAQC,OAAOC,KAAKP,KAAAA;UACpBQ,WAAWT;QACb,CAAA;MACF,OAAO;AACL,aAAK3B,aAAaqC,KAAKT,KAAAA;MACzB;IACF,OAAO;AACL,YAAMU,gBAAgB,KAAKxC,gBAAgByC,IAAItB,SAAAA;AAC/CqB,oBAAcL,SAASC,OAAOM,OAAO;QAACF,cAAcL;QAAQL;OAAM;AAClE,UAAIU,cAAcL,OAAOF,SAASO,cAAcF,WAAW;AACzD;MACF;AACA,YAAMV,OAAMY,cAAcL;AAC1B,WAAKnC,gBAAgB2C,OAAOxB,SAAAA;AAC5B,WAAKjB,aAAaqC,KAAKX,IAAAA;IACzB;EACF;EAEQgB,mBAAmB;AACzB,QAAI,KAAK9C,aAAakC,IAAI,KAAKvC,aAAa,GAAG;AAC7C,aAAO,KAAKA;IACd;AAEA,UAAMoD,QAAQ,KAAKnD;AACnB,SAAKA,oBAAoB,KAAKA,mBAAmB,KAAK,KAAKC,UAAUsC;AAErE,WAAO,KAAKtC,UAAUkD,KAAAA;EACxB;EAEQzB,cAAcH,MAAkBC,SAAkBC,WAAmB;AAC3E,QAAI,CAAC,KAAKxB,UAAUmD,SAAS3B,SAAAA,GAAY;AACvC,YAAM,IAAI4B,MAAM,mBAAmB5B,SAAAA,EAAW;IAChD;AAEA,QAAI,CAAC,KAAKrB,aAAakC,IAAIb,SAAAA,GAAY;AACrC,WAAKrB,aAAaoC,IAAIf,WAAW,CAAA,CAAE;IACrC;AAEA,UAAM6B,aAAa,KAAKlD,aAAa2C,IAAItB,SAAAA;AAEzC,UAAM8B,SAAS,CAAA;AACf,aAASC,MAAM,GAAGA,MAAMjC,KAAKgB,QAAQiB,OAAO5D,gBAAgB;AAC1D2D,aAAO5C,KAAKY,KAAKkC,SAASD,KAAKA,MAAM5D,cAAAA,CAAAA;IACvC;AAEA2D,WAAOG,QAAQ,CAACtB,OAAOe,UAAAA;AACrB,YAAMjB,MAAMyB,YAAY;QACtBvB;QACAX;QACAU,YAAYgB,UAAU,IAAI5B,KAAKgB,SAASqB;MAC1C,CAAA;AACAN,iBAAW3C,KAAK;QAAEuB;QAAKV,SAAS2B,UAAUI,OAAOhB,SAAS,IAAIf,UAAUoC;MAAU,CAAA;IACpF,CAAA;EACF;;EAIQC,gBAAsC;AAC5C,QAAIzB;AACJ,WAAO,KAAKhC,aAAae,OAAO,GAAG;AACjC,YAAMM,YAAY,KAAKyB,iBAAgB;AACvC,YAAMI,aAAa,KAAKlD,aAAa2C,IAAItB,SAAAA;AACzC,UAAI,CAAC6B,YAAY;AACf;MACF;AAEAlB,cAAQkB,WAAWQ,MAAK;AACxB,UAAI,CAAC1B,OAAO;AACV;MACF;AACA,UAAIkB,WAAWf,WAAW,GAAG;AAC3B,aAAKnC,aAAa6C,OAAOxB,SAAAA;MAC3B;AACA,aAAOW;IACT;AACA,WAAO;EACT;EAEA,MAAcT,cAAc;AAC1B,QAAI,KAAKpB,UAAU;AACjB;IACF;AACA,SAAKA,WAAW;AAChB,QAAI6B;AACJA,YAAQ,KAAKyB,cAAa;AAC1B,WAAOzB,OAAO;AAEZ,UAAI,CAAC,KAAKlC,QAAQ6D,UAAU;AAC1BjC,QAAAA,KAAI,mBAAA,QAAA;;;;;;AACJ,cAAM,KAAK5B,QAAQ8D,MAAMC,aAAa,CAAA;AACtCnC,QAAAA,KAAI,oBAAA,QAAA;;;;;;MACN;AACA,UAAI;AACF,cAAM,KAAK5B,QAAQU,KAAKsD,KAAK9B,MAAMF,GAAG;AACtCE,cAAMZ,SAAS2C,KAAAA;MACjB,SAAStC,KAAU;AACjBC,QAAAA,KAAI,uBAAuB;UAAED;QAAI,GAAA;;;;;;AACjCO,cAAMZ,SAAS4C,MAAMvC,GAAAA;MACvB;AACAO,cAAQ,KAAKyB,cAAa;IAC5B;AACAQ,IAAAA,WAAU,KAAKjE,aAAae,SAAS,GAAG,yBAAA;;;;;;;;;AACxC,SAAKZ,WAAW;EAClB;AACF;AAEO,IAAMoD,cAAc,CAAC,EAAElC,WAAWU,YAAYC,MAAK,MAAS;AACjE,QAAMkC,mBAA0BC,sBAAe9C,SAAAA;AAC/C,QAAM+C,mBAAmBrC,aAAoBoC,sBAAepC,UAAAA,IAAc;AAC1E,QAAMsC,UAAU/B,OAAOgC,YAAYJ,mBAAmBE,mBAAmBpC,MAAMG,MAAM;AACrFoC,EAAOC,cAAOnD,WAAWgD,OAAAA;AACzB,MAAItC,YAAY;AACdwC,IAAOC,cAAOzC,YAAYsC,SAASH,gBAAAA;EACrC;AACAG,UAAQjC,IAAIJ,OAAOkC,mBAAmBE,gBAAAA;AACtC,SAAOC;AACT;AAEO,IAAMpC,cAAc,CAACd,MAAkBsD,eAAAA;AAC5C,QAAMpD,YAAmBqD,cAAOvD,IAAAA;AAChC,MAAIY;AACJ,MAAI4C,SAAgBD,cAAOE;AAE3B,MAAIH,WAAWpD,SAAAA,GAAY;AACzBU,iBAAoB2C,cAAOvD,MAAMwD,MAAAA;AACjCA,cAAiBD,cAAOE;EAC1B;AAEA,QAAM5C,QAAQb,KAAKkC,SAASsB,MAAAA;AAE5B,SAAO;IAAEtD;IAAWU;IAAYC;EAAM;AACxC;;;;;;;;;;;;;;AD1MA,IAAM6C,UAAUC,QAAOC,gBAAgB,yBAAA;AAEvC,IAAMC,+BAA+B;AACrC,IAAMC,+BAA+B;AA0BrC,IAAMC,iBAAiB;AACvB,IAAMC,sBAAsB;AAC5B,IAAMC,oBAAoB;AAC1B,IAAMC,yBAAyB;AAmDxB,IAAMC,QAAN,MAAMA;EAqBXC,cAAc;AApBGC,qBAAY,IAAIC,SAASL,iBAAAA;AACzBM,8BAAqB,oBAAIC,IAAAA;AACzBC,0BAAiB,oBAAID,IAAAA;AACrBE,gBAAO,IAAIC,SAAAA,QAAAA;;;;AAGpBC,mBAAU;AAEVC,oBAAW;AACXC,uBAAc;AACdC,qBAAY;AAEZC,sBAA0BC;AACjBC,6BAAoB,oBAAIV,IAAAA;AAElCW,uBAAc,IAAIC,OAAAA;AAClBC,wBAAe,IAAID,OAAAA;AAEVE,kBAAS,KAAKjB,UAAUiB;AAItC,SAAKjB,UAAUkB,aAAaC,GAAG,OAAOC,QAAAA;AACpC,YAAM,KAAKC,eAAehC,QAAQiC,OAAOF,GAAAA,CAAAA;IAC3C,CAAA;EACF;EAEAG,aAAaC,WAAsB;AACjC,SAAKC,aAAaD;EACpB;EAEA,IACIE,kBAA0B;AAC5B,WAAO,KAAKD,aAAa,KAAKA,WAAWE,SAAQ,IAAK;EACxD;;;;;;;EAQA,MAAMC,aAAaC,KAAaC,OAA0B,CAAC,GAAoB;AAC7E,UAAMC,UAAU,KAAKC,mBAAmB;MACtCH;MACAI,aAAaH,KAAKG;IACpB,CAAA;AACAC,IAAAA,WAAU,CAACH,QAAQI,MAAM,yBAAyBN,GAAAA,IAAK;;;;;;;;;AAEvD,UAAMZ,SAAS,IAAImB,QAAO;MACxBC,OAAO,CAACC,MAAMC,UAAUC,aAAAA;AACtB,aAAKC,UAAUV,SAASO,IAAAA,EACrBI,KAAK,MAAMF,SAAAA,CAAAA,EACXG,MAAMH,QAAAA;MAEX;MACAI,MAAM,MAAA;MAAO;IACf,CAAA;AAEAb,YAAQI,OAAO,CAACG,SAAAA;AACdP,cAAQc,MAAMC,iBAAiBR,KAAKS;AACpC9B,aAAOkB,KAAKG,IAAAA;IACd;AACAP,YAAQiB,UAAU,CAACC,QAAAA;AAEjB,UAAIA,KAAK;AACP,YAAIhC,OAAOiC,UAAU,OAAA,EAASH,SAAS,GAAG;AACxC9B,iBAAO+B,QAAQC,GAAAA;QACjB,OAAO;AACLhC,iBAAO+B,QAAO;QAChB;MACF,OAAO;AACL/B,eAAO+B,QAAO;MAChB;IACF;AAGA,QAAI;AACF,YAAM,KAAKG,aACT;QACEC,aAAa;UACXC,IAAItB,QAAQsB;UACZxB,KAAKE,QAAQF;UACbI,aAAaF,QAAQE;QACvB;MACF,GACArC,iBAAAA;IAEJ,SAASqD,KAAU;AACjB,WAAKK,gBAAgBvB,SAASkB,GAAAA;AAC9B,YAAMA;IACR;AAEA,WAAOhC;EACT;;;;;;;EAQA,MAAMsC,WAAW1B,KAAaC,OAA0B,CAAC,GAAqB;AAC5E,UAAMC,UAAU,KAAKC,mBAAmB;MACtCH;MACAI,aAAaH,KAAKG;IACpB,CAAA;AACAC,IAAAA,WAAU,CAACH,QAAQI,MAAM,yBAAyBN,GAAAA,IAAK;;;;;;;;;AAGvD,QAAI2B,gBAA8B,CAAA;AAClC,QAAIhB;AAEJT,YAAQI,OAAO,CAACG,SAAAA;AACdP,cAAQc,MAAMC,iBAAiBR,KAAKS;AACpC,UAAIP,UAAU;AACZA,iBAASF,IAAAA;MACX,OAAO;AACLkB,sBAAcrB,KAAKG,IAAAA;MACrB;IACF;AAEA,UAAMmB,OAAgB;MACpBC,MAAM,OAAOpB,MAAkBqB,YAAAA;AAC7B,cAAM,KAAKlB,UAAUV,SAASO,MAAMqB,OAAAA;MAGtC;MACAC,WAAW,CAACC,OAAAA;AACV3B,QAAAA,WAAU,CAACM,UAAU,kCAAA;;;;;;;;;AACrBA,mBAAWqB;AACX,mBAAWvB,QAAQkB,eAAe;AAChCK,aAAGvB,IAAAA;QACL;AACAkB,wBAAgB,CAAA;MAClB;IACF;AAGA,QAAI;AACF,YAAM,KAAKL,aACT;QACEC,aAAa;UACXC,IAAItB,QAAQsB;UACZxB,KAAKE,QAAQF;UACbI,aAAaF,QAAQE;QACvB;MACF,GACArC,iBAAAA;IAEJ,SAASqD,KAAU;AACjB,WAAKK,gBAAgBvB,SAASkB,GAAAA;AAC9B,YAAMA;IACR;AAEA,WAAOQ;EACT;;EAIA,MAAMK,MAAMb,KAAa;AACvB,QAAI,KAAKxC,aAAa;AACpBsD,MAAAA,KAAI,uDAAA,QAAA;;;;;;AACJ;IACF;AACA,QAAI,KAAKvD,UAAU;AACjBuD,MAAAA,KAAI,oDAAA,QAAA;;;;;;AACJ;IACF;AAEA,SAAKvD,WAAW;AAEhB,UAAM,KAAK2C,aACT;MACEW,OAAO;QACLE,OAAOf,KAAKgB;MACd;IACF,GACArE,mBACAH,4BAAAA,EACAkD,MAAM,OAAOM,SAAAA;AACbc,MAAAA,KAAI,+BAA+B;QAAEd,KAAAA;MAAI,GAAA;;;;;;AAEzC,YAAM,KAAKiB,SAASjB,IAAAA;IACtB,CAAA;AAGA,UAAMkB,cAAa,KAAKD,SAASjB,GAAAA,GAAMpD,wBAAwB,IAAIuE,aAAa,0BAAA,CAAA;EAClF;;EAIA,MAAMpB,QAAQC,KAAa;AACzB,QAAI,KAAKxC,aAAa;AACpBsD,MAAAA,KAAI,gDAAA,QAAA;;;;;;AACJ;IACF;AACA,SAAKtD,cAAc;AACnB,SAAK,KAAKJ,KAAKgE,QAAO;AACtB,QAAI,KAAK7D,UAAU;AACjBuD,MAAAA,KAAI,qCAAA,QAAA;;;;;;AACJ,WAAKvD,WAAW;IAClB,OAAO;AAGL,YAAM,KAAK2C,aACT;QACEW,OAAO;UACLE,OAAOf,KAAKgB;QACd;MACF,GACArE,iBAAAA,EACA+C,MAAM,OAAOM,SAAAA;AACbc,QAAAA,KAAI,wCAAwC;UAAEd,KAAAA;QAAI,GAAA;;;;;;MACpD,CAAA;IACF;AAEA,SAAKiB,SAASjB,GAAAA,EAAKN,MAAM,CAACM,SAAAA;AACxBc,MAAAA,KAAI,iCAAiC;QAAEd,KAAAA;MAAI,GAAA;;;;;;IAC7C,CAAA;EACF;;EAIA,MAAMiB,SAASjB,KAAa;AAC1B,QAAI,KAAKvC,WAAW;AAClBqD,MAAAA,KAAI,+CAAA,QAAA;;;;;;AACJ;IACF;AAEA,SAAK,KAAK1D,KAAKgE,QAAO;AAEtB,UAAM,KAAKrE,UAAUgD,QAAO;AAE5B,eAAWjB,WAAW,KAAK3B,eAAekE,OAAM,GAAI;AAClDvC,cAAQiB,UAAUC,GAAAA;IACpB;AACA,SAAKvC,YAAY;AACjB,UAAM,KAAK6D,WAAU;AAErB,SAAKzD,YAAY0D,KAAKvB,GAAAA;AAGtB,SAAK/C,mBAAmBuE,MAAK;AAC7B,SAAKrE,eAAeqE,MAAK;EAC3B;EAEA,MAAcpD,eAAeqD,KAAc;AACzC,QAAI,KAAKhE,WAAW;AAClBqD,MAAAA,KAAIY,KAAK,mCAAmC;QAAED;MAAI,GAAA;;;;;;AAClD;IACF;AAEA,QAAIA,IAAIZ,OAAO;AACb,UAAI,CAAC,KAAKtD,UAAU;AAClBuD,QAAAA,KAAI,yDAAA,QAAA;;;;;;AACJ,cAAM,KAAKD,MAAM,IAAIc,MAAM,qBAAA,CAAA;MAC7B,OAAO;AACLb,QAAAA,KAAI,6CAAA,QAAA;;;;;;MACN;AAEA;IACF;AAEA,QAAIW,IAAItB,aAAa;AACnB,YAAMrB,UAAU,KAAKC,mBAAmB;QACtCH,KAAK6C,IAAItB,YAAYvB;QACrBI,aAAayC,IAAItB,YAAYnB;MAC/B,CAAA;AACAF,cAAQ8C,WAAWH,IAAItB,YAAYC;AAGnC,iBAAWf,QAAQP,QAAQ+C,QAAQ;AACjC,cAAM,KAAK3B,aACT;UACEb,MAAM;YACJyC,WAAWhD,QAAQ8C;YACnBvC;UACF;QACF,GACAP,QAAQsB,EAAE;MAEd;AACAtB,cAAQ+C,SAAS,CAAA;IACnB,WAAWJ,IAAIpC,MAAM;AACnB,YAAMrB,SAAS,KAAKf,mBAAmB8E,IAAIN,IAAIpC,KAAKyC,SAAS,KAAKE,cAAAA;AAClE,UAAI,CAAChE,OAAOkB,MAAM;AAChB4B,QAAAA,KAAIY,KAAK,kDAAkD;UAAE9C,KAAKZ,OAAOY;QAAI,GAAA;;;;;;AAC7E;MACF;AACAZ,aAAOkB,KAAKuC,IAAIpC,KAAKA,IAAI;IAC3B;EACF;EAEA,MAAca,aAAauB,KAAcK,YAAY,IAAIpB,UAAUnE,8BAA8B;AAC/F,QAAI,KAAKkB,WAAW;AAElB;IACF;AACA,QAAI;AACF,YAAMwE,UAAU,IAAIC,QAAAA;AACpB,WAAKnF,UAAUoF,SAAS/F,QAAQgG,OAAOX,GAAAA,GAAMQ,SAASH,SAAAA;AACtD,YAAMG,QAAQI,KAAK;QAAE3B;MAAQ,CAAA;IAC/B,SAASV,KAAU;AACjB,YAAM,KAAKD,QAAQC,GAAAA;IACrB;EACF;EAEQjB,mBAAmBuD,QAA8C;AACvE,QAAI,KAAKnF,eAAeoF,SAAS,GAAG;AAClCC,MAAAA,sBAAqB,KAAKpF,MAAM,YAAY,KAAKkE,WAAU,GAAI7E,cAAAA;IACjE;AACA,QAAIqC,UAAU,KAAK3B,eAAe4E,IAAIO,OAAO1D,GAAG;AAChD,QAAI,CAACE,SAAS;AACZA,gBAAU;QACRsB,IAAI,KAAK9C;QACTsE,UAAU;QACVhD,KAAK0D,OAAO1D;QACZI,aAAasD,OAAOtD;QACpB6C,QAAQ,CAAA;QACR3C,MAAM;QACNa,SAAS;QACTH,OAAO;UACL6C,WAAW;UACX5C,eAAe;QACjB;MACF;AACA,WAAK1C,eAAeuF,IAAI5D,QAAQF,KAAKE,OAAAA;AACrC,WAAK7B,mBAAmByF,IAAI5D,QAAQsB,IAAItB,OAAAA;AACxC,WAAK/B,UAAU4F,WAAW7D,QAAQsB,EAAE;IACtC;AAEA,WAAOtB;EACT;EAEA,MAAcU,UAAUV,SAAkBO,MAAkBqB,SAAiC;AAC3F,QAAIrB,KAAKS,SAASpD,qBAAqB;AACrCoE,MAAAA,KAAIY,KAAK,yCAAyC;QAAEa,MAAMlD,KAAKS;QAAQ8C,WAAWlG;MAAoB,GAAA;;;;;;IACxG;AAEAoC,YAAQc,MAAM6C,aAAapD,KAAKS;AAChC,QAAIhB,QAAQ8C,aAAa,MAAM;AAE7B9C,cAAQ+C,OAAO3C,KAAKG,IAAAA;AACpB;IACF;AACA,UAAM,KAAKa,aACT;MACEb,MAAM;QACJyC,WAAWhD,QAAQ8C;QACnBvC;MACF;IACF,GACAP,QAAQsB,IACRM,OAAAA;EAEJ;EAEQL,gBAAgBvB,SAAkBkB,KAAa;AACrD,QAAIlB,QAAQiB,SAAS;AACnBjB,cAAQiB,QAAQC,GAAAA;IAClB;AAEA,SAAK/C,mBAAmB4F,OAAO/D,QAAQsB,EAAE;AACzC,SAAKjD,eAAe0F,OAAO/D,QAAQF,GAAG;EACxC;EAEA,MAAc0C,aAAa;AACzB,QAAI,KAAK7D,aAAa,KAAKD,aAAa;AACtC,UAAI,CAAC,KAAKE,YAAY;AACpB;MACF;AAGA,YAAMoF,YAAY,KAAKpF;AACvB,WAAKA,aAAaC;AAElBmF,gBAAUC,iBAAiB;AAC3BD,gBAAUE,kBAAkB;AAC5B,iBAAWC,KAAKH,UAAUI,UAAU;AAClCD,UAAED,kBAAkB;MACtB;AACA,WAAKjF,aAAawD,KAAKuB,SAAAA;AAEvB,WAAKlF,kBAAkB4D,MAAK;AAC5B;IACF;AAEA,UAAMiB,YAAY,KAAK1F,UAAU0F;AACjC,UAAM5C,gBAAgB,KAAK9C,UAAU8C;AAErC,UAAMsD,MAAMC,KAAKD,IAAG;AACpB,UAAME,WAAW,KAAK3F,cAAcyF,MAAM,KAAKzF,WAAW4F,aAAa,MAAQ;AAC/E,UAAMC,sBAAsB,CAACC,SAA2BC,SACtDA,OACI;MACEC,eAAeL,YAAYG,QAAQf,YAAYgB,KAAKhB,aAAaY,WAAW1F;MAC5EgG,mBAAmBN,YAAYG,QAAQ3D,gBAAgB4D,KAAK5D,iBAAiBwD,WAAW1F;IAC1F,IACA,CAAC;AAEP,SAAKD,aAAa;MAChB4F,WAAWH;MACXD,UAAUU,MAAMC,KAAK,KAAK1G,eAAekE,OAAM,CAAA,EAAIyC,IAAI,CAAChF,YAAAA;AACtD,cAAMc,QAAoC;UACxCQ,IAAItB,QAAQsB;UACZxB,KAAKE,QAAQF;UACbI,aAAaF,QAAQE;UACrBgE,iBAAiBlE,QAAQ+C,OAAO/B;UAChC2C,WAAW3D,QAAQc,MAAM6C;UACzB5C,eAAef,QAAQc,MAAMC;UAC7B,GAAG0D,oBAAoBzE,QAAQc,OAAO,KAAKhC,kBAAkBmE,IAAIjD,QAAQsB,EAAE,CAAA;QAC7E;AAEA,aAAKxC,kBAAkB8E,IAAI5D,QAAQsB,IAAIR,KAAAA;AACvC,eAAOA;MACT,CAAA;MACA6C;MACA5C;MACA,GAAG0D,oBAAoB;QAAEd;QAAW5C;MAAc,GAAG,KAAKnC,UAAU;MACpEqF,gBAAgB,KAAKhG,UAAUiB,OAAO+F;MACtCf,iBAAiB,KAAKjG,UAAUiB,OAAOgG;IACzC;AAEA,SAAKjG,aAAawD,KAAK,KAAK7D,UAAU;EACxC;AACF;;EA3YGuG;GAhCUpH,MAAAA,WAAAA,mBAAAA,IAAAA;;;;;;;;;;;;;;AH7Eb,IAAMqH,6BAA6B;AACnC,IAAMC,4BAA4B;AAK3B,IAAMC,WAAN,MAAMA;EA6BXC,YAAY,EAAEC,WAAWC,aAAaC,cAAc,GAAGC,KAAAA,GAAwB;AAvB9DC,gBAAO,IAAIC,SAAQ;MAClCC,SAAS,CAACC,QAAAA;AACR,aAAK,KAAKC,QAAQD,GAAAA,EAAKE,MAAM,MAAA;AAC3BC,UAAAA,KAAIC,MAAM,wBAAwBJ,KAAAA;;;;;;QACpC,CAAA;MACF;IACF,GAAA;;;;AAEiBK,kBAAS,IAAIC,MAAAA;AAIbC,uBAAc,oBAAIC,IAAAA;AAClBC,6BAAoB,oBAAIC,IAAAA;AAEjCC,iBAAQ;AACRC,uBAAc;AACdC,qBAAY;AAOlBC,IAAAA,WAAU,OAAOrB,cAAc,WAAA,QAAA;;;;;;;;;AAC/BqB,IAAAA,WAAUC,UAAUC,YAAYtB,WAAAA,GAAAA,QAAAA;;;;;;;;;AAChCoB,IAAAA,WAAUC,UAAUC,YAAYrB,YAAAA,GAAAA,QAAAA;;;;;;;;;AAChC,SAAKF,YAAYA;AACjB,SAAKC,cAAcA;AACnB,SAAKC,eAAeA;AAEpB,SAAKsB,WAAW,IAAIC,iBAClB;MACEC,mBAAmBvB,KAAKwB,4BAA4B/B;MACpDgC,kBAAkBzB,KAAK0B,2BAA2BhC;MAClDiC,WAAW,MAAA;AACT,YAAI,KAAKX,eAAe,KAAKC,WAAW;AACtC;QACF;AACAV,QAAAA,KAAIqB,KAAK,uDAAA,QAAA;;;;;;AACT,aAAKC,MAAM,IAAIC,cAAa,mBAAA,CAAA,EAAsBxB,MAAM,CAACF,QAAQG,KAAID,MAAMF,KAAAA,QAAAA;;;;;;MAC7E;IACF,GACA,KAAKN,aACL,KAAKC,YAAY;AAGnB,SAAKsB,SAASU,sBAAsBC,IAAI,OAAOC,SAAAA;AAC7C1B,MAAAA,KAAI,oBAAoB;QAAE0B;MAAK,GAAA;;;;;;AAC/Bf,MAAAA,WAAU,CAAC,KAAKL,kBAAkBqB,IAAID,IAAAA,GAAO,mCAAA;;;;;;;;;AAC7C,WAAKpB,kBAAkBsB,IAAIF,IAAAA;AAE3B,UAAI,KAAKtB,YAAYuB,IAAID,IAAAA,GAAO;AAC9B,YAAI;AACF,gBAAM,KAAKG,eAAeH,IAAAA;QAC5B,SAAS7B,KAAU;AACjB,gBAAM,KAAKC,QAAQD,GAAAA;QACrB;MACF;IACF,CAAA;AAEA;AAEE,WAAKK,OAAO4B,OAAOC,GAAG,SAAS,YAAA;AAC7B,YAAI,KAAKtB,eAAe,KAAKC,WAAW;AACtCV,UAAAA,KAAI,2FAAA,QAAA;;;;;;AACJ;QACF;AACA,cAAM,KAAKF,QAAO;MACpB,CAAA;AAEA,WAAKI,OAAO4B,OAAOC,GAAG,SAAS,OAAOlC,QAAAA;AACpC,cAAM,KAAKC,QAAQD,GAAAA;MACrB,CAAA;IACF;AAGA,SAAKK,OAAO8B,aAAaD,GAAG,CAACE,UAAAA;AAC3BjC,MAAAA,KAAIkC,MAAM,4BAA4B;QACpC3C;QACAC;QACA2C,WAAWF,MAAME;QACjBC,eAAeH,MAAMG;QACrBC,eAAeJ,MAAMI;QACrBC,mBAAmBL,MAAMK;QACzBC,UAAUN,MAAMM;MAClB,GAAA;;;;;;IAGF,CAAA;EACF;EAvEA,IAAWC,SAAS;AAClB,WAAO,KAAKhC;EACd;EAuEA,IACIiC,kBAA0B;AAC5B,WAAO,KAAKC,aAAa,KAAKA,WAAWC,SAAQ,IAAK;EACxD;EAEA,IAAIb,SAAiB;AACnB,WAAO,KAAK5B,OAAO4B;EACrB;EAEA,IAAIG,QAA2B;AAC7B,WAAO,KAAK/B,OAAO8B;EACrB;;;;EAMA,MAAMY,KAAKC,YAAuBjC,UAAUkC,OAAM,GAAI;AAEpD,SAAKJ,aAAaG;AAClB7C,IAAAA,KAAI,QAAA,QAAA;;;;;;AACJ,SAAK+C,cAAc,8BAA8B,KAAKjC,QAAQ;AAC9D,UAAM,KAAKe,eAAe,4BAAA;AAC1B,SAAKrB,QAAQ;AACb,SAAKN,OAAO8C,aAAaH,SAAAA;EAC3B;EAEA,MAAMI,MAAMpD,KAAa;AAEvB,UAAM,KAAKC,QAAQD,GAAAA;EACrB;EAEA,MACMyB,MAAMzB,KAAa;AACvB,QAAI,KAAKa,aAAa,KAAKD,aAAa;AACtC;IACF;AACA,SAAKC,YAAY;AACjB,SAAKF,QAAQ;AAEb,QAAI,KAAKd,KAAKwD,UAAU;AACtB;IACF;AAEA,UAAM,KAAKxD,KAAKyD,QAAO;AAEvB,eAAWC,aAAa,KAAKhD,YAAYiD,OAAM,GAAI;AACjD,UAAI;AACF,cAAMD,UAAUE,QAAQzD,GAAAA;MAC1B,SAASA,MAAU;AACjBG,QAAAA,KAAID,MAAMF,MAAAA,QAAAA;;;;;;MACZ;IACF;AAEA,UAAM,KAAKK,OAAOJ,QAAQD,GAAAA;EAC5B;EAEA,MAEMC,QAAQD,KAAa;AACzB,QAAI,KAAKY,eAAe,KAAKC,WAAW;AACtC;IACF;AACAV,IAAAA,KAAI,0BAA0B;MAAEuD,iBAAiB,KAAKnD,YAAYoD;IAAK,GAAA;;;;;;AACvE,SAAK/C,cAAc;AACnB,SAAKD,QAAQ;AAEb,QAAI,KAAKd,KAAKwD,UAAU;AACtB;IACF;AAEA,UAAM,KAAKxD,KAAKyD,QAAO;AAEvB,eAAWC,aAAa,KAAKhD,YAAYiD,OAAM,GAAI;AACjD,UAAI;AACFrD,QAAAA,KAAI,wBAAwB;UAAE0B,MAAM0B,UAAU/D,YAAYqC;QAAK,GAAA;;;;;;AAC/D,cAAM0B,UAAUK,QAAQ5D,GAAAA;AACxBG,QAAAA,KAAI,uBAAuB;UAAE0B,MAAM0B,UAAU/D,YAAYqC;QAAK,GAAA;;;;;;MAChE,SAAS7B,MAAU;AACjBG,QAAAA,KAAID,MAAMF,MAAAA,QAAAA;;;;;;MACZ;IACF;AAEA,UAAM,KAAKK,OAAO+C,MAAK;AACvBjD,IAAAA,KAAI,sBAAA,QAAA;;;;;;EACN;EAEA0D,aAAahC,MAAc0B,WAA8B;AACvD,QAAI,CAAC,KAAK5C,OAAO;AACf,YAAM,IAAImD,MAAM,UAAA;IAClB;AAEA3D,IAAAA,KAAI,gBAAgB;MAAE0B;IAAK,GAAA;;;;;;AAC3B,SAAKqB,cAAcrB,MAAM0B,SAAAA;AAGzBQ,iBAAa,KAAKlE,MAAM,YAAA;AACtB,UAAI;AACF,cAAM,KAAKoB,SAAS+C,kBAAkBnC,IAAAA;MACxC,SAAS7B,KAAK;AACZ,YAAIA,eAAeiE,iBAAgB;AACjC;QACF;AACA,cAAMjE;MACR;IACF,CAAA;AAEA,QAAI,KAAKS,kBAAkBqB,IAAID,IAAAA,GAAO;AAEpCkC,mBAAa,KAAKlE,MAAM,YAAA;AACtB,cAAM,KAAKmC,eAAeH,IAAAA;MAC5B,CAAA;IACF;EACF;EAEQqB,cAAcgB,eAAuBX,WAA8B;AACzEzC,IAAAA,WAAU,CAACoD,cAAcC,SAAS,GAAA,GAAM,0BAAA;;;;;;;;;AACxCrD,IAAAA,WAAU,CAAC,KAAKP,YAAYuB,IAAIoC,aAAAA,GAAgB,4BAAA;;;;;;;;;AAChD,SAAK3D,YAAYqB,IAAIsC,eAAeX,SAAAA;EACtC;EAEA,MAAcvB,eAAekC,eAAuB;AAClD/D,IAAAA,KAAI,kBAAkB;MAAE+D;IAAc,GAAA;;;;;;AACtC,UAAMX,YAAY,KAAKhD,YAAY6D,IAAIF,aAAAA,KAAkBG,eAAAA;AAEzD,UAAMC,UAA4B;MAChC7E,WAAW,KAAKA;MAChBC,aAAa,KAAKA;MAClBC,cAAc,KAAKA;MACnB4E,YAAY,OAAOC,aAAqBC,SAAAA;AACtC3D,QAAAA,WAAU,CAAC0D,YAAYL,SAAS,GAAA,GAAM,wBAAA;;;;;;;;;AACtC,eAAO,KAAK9D,OAAOkE,WAAW,GAAGL,aAAAA,IAAiBM,WAAAA,IAAeC,IAAAA;MACnE;MACAC,cAAc,OAAOF,aAAqBC,SAAAA;AACxC3D,QAAAA,WAAU,CAAC0D,YAAYL,SAAS,GAAA,GAAM,wBAAA;;;;;;;;;AACtC,eAAO,KAAK9D,OAAOqE,aAAa,GAAGR,aAAAA,IAAiBM,WAAAA,IAAeC,IAAAA;MACrE;MACArB,OAAO,CAACpD,QAAAA;AACN,aAAK2E,kBAAkB,KAAK9E,MAAM,YAAA;AAChC,gBAAM,KAAKuD,MAAMpD,GAAAA;QACnB,CAAA;MACF;IACF;AAEA,UAAMuD,UAAUqB,OAAON,OAAAA;AACvBnE,IAAAA,KAAI,oBAAoB;MAAE+D;IAAc,GAAA;;;;;;EAC1C;AACF;;EAnJGW;GAlGUtF,SAAAA,WAAAA,mBAAAA,IAAAA;;EAkIVuF;GAlIUvF,SAAAA,WAAAA,SAAAA,IAAAA;;EA2JVuF;GA3JUvF,SAAAA,WAAAA,WAAAA,IAAAA;;;;ADdN,IAAMwF,cAAN,MAAMA;EAAN;AACYC,kBAAS,oBAAIC,IAAAA;;EAE9BC,WAA+BC,MAA4B;AACzD,UAAMC,OAAOD,KAAKE,QAAO;AACzB,SAAKL,OAAOM,IAAIF,IAAAA;AAChB,WAAOA;EACT;EAEA,CAACG,YAAgCJ,MAAuC;AACtE,WAAO,MAAM;AACX,YAAM,KAAKD,WAAWC,IAAAA;IACxB;EACF;EAEA,MAAMK,UAAU;AACd,UAAMC,QAAQC,IAAIC,MAAMC,KAAK,KAAKZ,MAAM,EAAEa,IAAI,CAACC,UAAUA,MAAMN,QAAO,CAAA,CAAA;EACxE;EAEA,MAAMO,QAAQC,OAAiBC,OAAiB;AAC9CC,IAAAA,WAAUF,UAAUC,OAAAA,QAAAA;;;;;;;;;AACpBC,IAAAA,WAAU,KAAKlB,OAAOmB,IAAIH,KAAAA,GAAAA,QAAAA;;;;;;;;;AAC1BE,IAAAA,WAAU,KAAKlB,OAAOmB,IAAIH,KAAAA,GAAAA,QAAAA;;;;;;;;;AAE1B,UAAMI,cAAcJ,MAAMK,iBAAiB;MAAEC,WAAW;MAAMC,cAAcN,MAAMO;IAAO,CAAA;AACzF,UAAMC,cAAcR,MAAMI,iBAAiB;MAAEC,WAAW;MAAOC,cAAcP,MAAMQ;IAAO,CAAA;AAE1FE,gBAAYN,YAAYO,SAASC,QAAQH,YAAYE,SAASC,MAAM;AACpE,UAAMnB,QAAQC,IAAI;MAACM,MAAMa,eAAeT,WAAAA;MAAcH,MAAMY,eAAeJ,WAAAA;KAAa;AAExF,WAAO;MAACL;MAAaK;;EACvB;EAEA,MAAMK,WAAWd,OAAiBC,OAAiB;AACjDC,IAAAA,WAAUF,UAAUC,OAAAA,QAAAA;;;;;;;;;AACpBC,IAAAA,WAAU,KAAKlB,OAAOmB,IAAIH,KAAAA,GAAAA,QAAAA;;;;;;;;;AAC1BE,IAAAA,WAAU,KAAKlB,OAAOmB,IAAIH,KAAAA,GAAAA,QAAAA;;;;;;;;;AAE1B,UAAMI,cAAcT,MAAMC,KAAKI,MAAMe,WAAW,EAAEC,KAAK,CAACC,eACtDA,WAAWV,aAAaW,OAAOjB,MAAMO,MAAM,CAAA;AAE7C,UAAMC,cAAcd,MAAMC,KAAKK,MAAMc,WAAW,EAAEC,KAAK,CAACC,eACtDA,WAAWV,aAAaW,OAAOlB,MAAMQ,MAAM,CAAA;AAG7CN,IAAAA,WAAUE,aAAAA,QAAAA;;;;;;;;;AACVF,IAAAA,WAAUO,aAAAA,QAAAA;;;;;;;;;AAEV,UAAMhB,QAAQC,IAAI;MAACM,MAAMmB,gBAAgBf,WAAAA;MAAcH,MAAMkB,gBAAgBV,WAAAA;KAAa;EAC5F;AACF;AAEO,IAAMW,WAAN,MAAMA;EAGXC,YAA4Bb,SAAoBc,WAAUC,OAAM,GAAI;SAAxCf,SAAAA;SAFZO,cAAc,oBAAI9B,IAAAA;EAEmC;EAErE,MAAgBuC,OAAOP,YAA4B;EAAC;EACpD,MAAgBQ,QAAQR,YAA4B;EAAC;EAErDZ,iBAAiB,EAAEC,WAAWC,aAAY,GAAqD;AAC7F,UAAMU,aAAa,IAAIS,eAAe,KAAKlB,QAAQD,cAAcD,SAAAA;AACjE,SAAKS,YAAYzB,IAAI2B,UAAAA;AACrB,WAAOA;EACT;EAEA,MAAMJ,eAAeI,YAA4B;AAC/Cf,IAAAA,WAAU,KAAKa,YAAYZ,IAAIc,UAAAA,GAAAA,QAAAA;;;;;;;;;AAC/B,UAAMA,WAAWN,SAASgB,KAAKL,WAAUC,OAAM,CAAA;AAC/C,UAAM,KAAKC,OAAOP,UAAAA;EACpB;EAEA,MAAME,gBAAgBF,YAA4B;AAChDf,IAAAA,WAAU,KAAKa,YAAYZ,IAAIc,UAAAA,GAAAA,QAAAA;;;;;;;;;AAC/B,UAAM,KAAKQ,QAAQR,UAAAA;AACnB,UAAMA,WAAWN,SAASiB,MAAK;AAC/B,SAAKb,YAAYc,OAAOZ,UAAAA;EAC1B;EAEA,MAAMzB,UAAU;AACd,eAAWmB,YAAY,KAAKI,aAAa;AACvC,YAAM,KAAKI,gBAAgBR,QAAAA;IAC7B;EACF;AACF;AAEA,IAAMD,cAAc,CAACoB,SAAiBC,YAAAA;AACpCC,WAASF,SAASC,SAAS,CAACE,QAAAA;AAC1B,QAAIA,OAAOA,IAAIC,SAAS,8BAA8B;AACpDC,MAAAA,KAAIC,MAAMH,KAAAA,QAAAA;;;;;;IACZ;EACF,CAAA;AACAD,WAASD,SAASD,SAAS,CAACG,QAAAA;AAC1B,QAAIA,OAAOA,IAAIC,SAAS,8BAA8B;AACpDC,MAAAA,KAAIC,MAAMH,KAAAA,QAAAA;;;;;;IACZ;EACF,CAAA;AACF;AAEO,IAAMP,iBAAN,MAAMA;EAGXL,YACkBgB,aACA9B,cACAD,WAChB;SAHgB+B,cAAAA;SACA9B,eAAAA;SACAD,YAAAA;AAEhB,SAAKK,WAAW,IAAI2B,SAAS;MAC3BhC;MACA+B;MACA9B;IACF,CAAA;EACF;EAEOgC,SAASZ,MAAe;AAC7B,WAAOa,iBAAiB;MAAEC,WAAW,MAAM,KAAK9B,SAAS+B,WAAWf;IAAK,CAAA;EAC3E;AACF;;;AMlIA,SAASgB,gBAAAA,eAAcC,WAAAA,gBAAe;AACtC,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,OAAAA,YAAW;AACpB,SAASC,UAAAA,eAAc;AAEvB,SAASC,sBAAAA,2BAA6C;;AAU/C,IAAMC,gBAAN,MAAMA;EAOXC,YAA4BC,YAAoC,CAAC,GAAG;SAAxCA,YAAAA;SANZC,OAAO,IAAIR,SAAAA;SACXS,SAAS,IAAIT,SAAAA;SACbU,UAAU,IAAIV,SAAAA;EAIuC;EAErE,IAAIW,eAAe;AACjB,WAAO,KAAKC,kBAAkBD;EAChC;EAEA,MAAME,OAAOC,SAA2B;AACtCZ,IAAAA,KAAI,UAAU;MAAEa,aAAaD,QAAQC;MAAaJ,cAAcG,QAAQH;IAAa,GAAA;;;;;;AACrF,SAAKC,mBAAmBE;AACxB,SAAKE,OAAOZ,oBAA+E;MACzFa,MAAM,MAAMH,QAAQI,WAAW,OAAO;QACpCC,aAAa;MACf,CAAA;MACAC,WAAW;QACTC,aAAalB,QAAOmB,WAAW,iCAAA;MACjC;MACAC,SAAS;QACPF,aAAalB,QAAOmB,WAAW,iCAAA;MACjC;MACAE,UAAU;QACRH,aAAa;UACXI,UAAU,OAAOC,YAAAA;UAEjB;UACAC,UAAU,OAAOD,YAAAA;AACf,mBAAO;cACLE,MAAMF,QAAQE;YAChB;UACF;QACF;MACF;MACAC,SAAS;IACX,CAAA;AAEA,UAAM,KAAKb,KAAKR,KAAI;AACpB,UAAM,KAAKD,UAAUM,SAAM;AAE3B,SAAKL,KAAKsB,KAAI;EAChB;EAEA,MAAMC,QAAQC,KAAa;AACzB9B,IAAAA,KAAI,WAAW;MAAE8B;IAAI,GAAA;;;;;;AACrB,UAAM,KAAKzB,UAAUwB,UAAO;AAC5B,SAAKtB,OAAOqB,KAAI;AAChB,UAAM,KAAKd,MAAMiB,MAAAA;EACnB;EAEA,MAAMC,QAAQF,KAAa;AACzB9B,IAAAA,KAAI,WAAW;MAAE8B;IAAI,GAAA;;;;;;AACrB,UAAM,KAAKzB,UAAU2B,UAAO;AAC5B,SAAKxB,QAAQoB,KAAI;AACjB,UAAM,KAAKd,MAAMmB,MAAAA;EACnB;EAEA,MAAMC,KAAKC,UAAU,QAAQ;AAC3B,UAAM,KAAK7B,KAAK8B,KAAK;MAAET,SAAS;IAAK,CAAA;AACrC,UAAMU,MAAM,MAAMxC,cAAa,KAAKiB,KAAKwB,IAAInB,YAAYM,SAAS;MAAEC,MAAMS;IAAQ,CAAA,GAAI,IAAA;AACtFpC,IAAAA,WAAUsC,IAAIX,SAASS,SAAAA,QAAAA;;;;;;;;;EACzB;;;;EAKA,MAAMI,gBAAgBT,KAAa;AACjC,SAAKpB,kBAAkBqB,MAAMD,GAAAA;EAC/B;AACF;;;ACxFA,SAASU,mBAAmB;AAG5B,SAASC,WAAAA,gBAAe;AACxB,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,OAAAA,YAAW;AACpB,SAASC,UAAAA,eAAc;AAEvB,SAASC,sBAAAA,2BAA6C;;AAU/C,IAAMC,2BAAN,MAAMA;EASXC,YAA4BC,YAA+C,CAAC,GAAG;SAAnDA,YAAAA;SARZC,OAAO,IAAIR,SAAAA;SACXS,SAAS,IAAIT,SAAAA;SACbU,UAAU,IAAIV,SAAAA;SACbW,WAAW,oBAAIC,IAAAA;EAKgD;EAEhF,IAAIC,eAAe;AACjB,WAAO,KAAKC,kBAAkBD;EAChC;EAEA,MAAcE,YAAYC,WAAmBC,WAAW,GAAGC,YAAY,MAAM;AAC3EjB,IAAAA,WAAU,CAAC,KAAKU,SAASQ,IAAIH,SAAAA,GAAY,0BAA0BA,SAAAA,IAAW;;;;;;;;;AAE9E,UAAMI,gBAAgB,MAAM,KAAKN,iBAAkBO,aAAaL,WAAW;MACzEM,aAAa;IACf,CAAA;AAEA,UAAMC,cAA0B;MAC9BH;MACAI,WAAW;MACXC,eAAe;MACfC,YAAY;MACZC,eAAe;MACfC,gBAAgBC,KAAKC,IAAG;IAC1B;AAEA,UAAMC,YAAY,MAAA;AAChBR,kBAAYS,QAAQC,WAAW,MAAA;AAC7B,cAAMC,QAAQnC,YAAYmB,SAAAA;AAE1B,YACE,CAACE,cAAce,MAAMD,OAAO,UAAU,CAACE,QAAAA;AACrC,cAAI,CAACA,KAAK;AACRb,wBAAYC,aAAaU,MAAMG;UACjC,OAAO;AACLd,wBAAYG,cAAc;UAC5B;QACF,CAAA,GACA;AACAN,wBAAckB,KAAK,SAASP,SAAAA;QAC9B,OAAO;AACLQ,kBAAQC,SAAST,SAAAA;QACnB;MACF,GAAGd,QAAAA;IACL;AAEAc,cAAAA;AAEA,SAAKpB,SAAS8B,IAAIzB,WAAWO,WAAAA;AAE7BH,kBAAcsB,GAAG,QAAQ,CAACC,SAAAA;AACxBpB,kBAAYE,iBAAiBkB,KAAKN;IACpC,CAAA;AAEAjB,kBAAcsB,GAAG,SAAS,CAACN,QAAAA;AACzBb,kBAAYI,iBAAiB;IAC/B,CAAA;AAEAP,kBAAcsB,GAAG,SAAS,MAAA;AACxBtB,oBAAcwB,mBAAkB;IAClC,CAAA;AAEArB,gBAAYsB,iBAAiBC,YAAY,MAAA;AACvC,YAAM,EAAEtB,WAAWC,eAAeC,YAAYC,cAAa,IAAKJ;AAEhErB,MAAAA,KAAI6C,MAAM,0BAA0B;QAClC/B;QACAQ;QACAC;QACAC;QACAC;QACAqB,MAAM,KAAKlC,kBAAkBmC;QAC7BC,IAAI,KAAKpC,kBAAkBD;MAC7B,GAAA;;;;;;IACF,GAAG,GAAA;EACL;EAEQsC,aAAanC,WAA0B;AAC7Cf,IAAAA,WAAU,KAAKU,SAASQ,IAAIH,SAAAA,GAAY,0BAA0BA,SAAAA,IAAW;;;;;;;;;AAE7E,UAAMoC,SAAS,KAAKzC,SAAS0C,IAAIrC,SAAAA;AAEjCsC,iBAAaF,OAAOpB,KAAK;AACzBsB,iBAAaF,OAAOP,cAAc;AAElC,UAAM,EAAErB,WAAWC,eAAeC,YAAYC,eAAeC,eAAc,IAAKwB;AAEhFA,WAAOhC,cAAcmC,QAAO;AAC5B,SAAK5C,SAAS6C,OAAOxC,SAAAA;AAErB,WAAO;MACLQ;MACAC;MACAC;MACAC;MACA8B,aAAa5B,KAAKC,IAAG,KAAMF,kBAAkB;IAC/C;EACF;EAEA,MAAM8B,OAAOC,SAA2B;AACtCzD,IAAAA,KAAI,UAAU;MAAE+C,aAAaU,QAAQV;MAAapC,cAAc8C,QAAQ9C;IAAa,GAAA;;;;;;AACrF,SAAKC,mBAAmB6C;AACxB,SAAKC,OAAOxD,oBAGV;MACAyD,MAAM,MAAMF,QAAQG,WAAW,OAAO;QACpCxC,aAAa;MACf,CAAA;MACAyC,WAAW;QACTC,wBAAwB7D,QAAO8D,WAAW,4CAAA;MAC5C;MACAC,SAAS;QACPF,wBAAwB7D,QAAO8D,WAAW,4CAAA;MAC5C;MACAE,UAAU;QACRH,wBAAwB;UACtBI,mBAAmB,OAAOC,YAAAA;AACxB,kBAAM,EAAE1B,MAAM3B,WAAWsD,oBAAoBC,oBAAmB,IAAKF;AAErE,kBAAM,KAAKtD,YAAYC,WAAWsD,oBAAoBC,mBAAAA;AAEtD,mBAAO;cACL5B,MAAM3B;YACR;UACF;UACAwD,iBAAiB,OAAOH,YAAAA;AACtB,kBAAMrD,YAAYqD,QAAQ1B;AAC1B,kBAAM,EAAEnB,WAAWC,eAAeC,YAAYC,eAAe8B,YAAW,IAAK,KAAKN,aAAanC,SAAAA;AAE/F,mBAAO;cACL2B,MAAM3B;cACNQ;cACAC;cACAC;cACAC;cACA8B;YACF;UACF;QACF;MACF;MACAgB,SAAS;IACX,CAAA;AAEA,UAAM,KAAKb,KAAKpD,KAAI;AACpB,UAAM,KAAKD,UAAUmD,SAAM;AAE3B,SAAKlD,KAAKkE,KAAI;EAChB;EAEA,MAAMC,QAAQvC,KAAa;AACzBlC,IAAAA,KAAI,WAAW;MAAEkC;IAAI,GAAA;;;;;;AACrB,UAAM,KAAK7B,UAAUoE,UAAO;AAC5B,SAAKlE,OAAOiE,KAAI;AAChB,eAAW,CAAC1D,WAAWoC,MAAAA,KAAWwB,OAAOC,QAAQ,KAAKlE,QAAQ,GAAG;AAC/DT,MAAAA,KAAI,kBAAkB;QAAEc;MAAU,GAAA;;;;;;AAClCsC,mBAAaF,OAAOnC,QAAQ;AAC5BmC,aAAOhC,cAAcmC,QAAO;IAC9B;AACA,UAAM,KAAKK,MAAMkB,MAAAA;EACnB;EAEA,MAAMC,QAAQ3C,KAAa;AACzBlC,IAAAA,KAAI,WAAW;MAAEkC;IAAI,GAAA;;;;;;AACrB,UAAM,KAAK7B,UAAUwE,UAAO;AAC5B,SAAKrE,QAAQgE,KAAI;AACjB,UAAM,KAAKd,MAAMoB,MAAAA;EACnB;EAEA,MAAMC,aAAaX,oBAA4BC,qBAA6BvD,WAAqC;AAC/G,UAAM,KAAKR,KAAK0E,KAAK;MAAET,SAAS;IAAK,CAAA;AACrC,QAAI,CAACzD,WAAW;AACdA,kBAAY,UAAUjB,YAAY,CAAA,EAAGoF,SAAS,KAAA,CAAA;IAChD;AACA,UAAM,EAAExC,KAAI,IAAK,MAAM,KAAKiB,KAAKwB,IAAIpB,uBAAuBI,kBAAkB;MAC5EzB,MAAM3B;MACNsD;MACAC;IACF,CAAA;AACAtE,IAAAA,WAAU0C,SAAS3B,WAAAA,QAAAA;;;;;;;;;AAEnB,UAAM,KAAKD,YAAYC,WAAWsD,oBAAoBC,mBAAAA;AACtD,WAAOvD;EACT;EAEA,MAAMqE,YAAYrE,WAA6C;AAC7D,UAAM,KAAKR,KAAK0E,KAAK;MAAET,SAAS;IAAK,CAAA;AACrC,UAAM,EAAE9B,MAAMnB,WAAWC,eAAeC,YAAYC,eAAe8B,YAAW,IAC5E,MAAM,KAAKG,KAAKwB,IAAIpB,uBAAuBQ,gBAAgB;MACzD7B,MAAM3B;IACR,CAAA;AAEFf,IAAAA,WAAU0C,SAAS3B,WAAAA,QAAAA;;;;;;;;;AAEnB,UAAMsE,QAAQ,KAAKnC,aAAanC,SAAAA;AAEhC,WAAO;MACLA;MACAuE,OAAO;QACLD;QACAE,QAAQ;UACNhE;UACAC;UACAC;UACAC;UACA8B;QACF;MACF;IACF;EACF;;;;EAKA,MAAMgC,gBAAgBrD,KAAa;AACjC,SAAKtB,kBAAkBgE,MAAM1C,GAAAA;EAC/B;AACF;",
|
6
|
+
"names": ["pipeline", "waitForCondition", "invariant", "PublicKey", "log", "runInContextAsync", "synchronized", "scheduleTask", "Context", "failUndefined", "invariant", "PublicKey", "log", "logInfo", "RpcClosedError", "TimeoutError", "asyncTimeout", "scheduleTaskInterval", "TimeoutError", "AsyncTimeoutError", "Context", "log", "schema", "RpcClosedError", "createProtoRpcPeer", "Callback", "HEARTBEAT_RTT_WARN_THRESH", "DEBUG_PRINT_HEARTBEAT", "ControlExtension", "constructor", "opts", "localPeerId", "remotePeerId", "_ctx", "onError", "err", "_extensionContext", "close", "onExtensionRegistered", "registerExtension", "name", "_rpc", "rpc", "Control", "onOpen", "extensionContext", "requested", "getService", "exposed", "handlers", "request", "call", "heartbeat", "ts", "requestTimestamp", "truncate", "port", "createPort", "contentType", "timeout", "heartbeatTimeout", "open", "reqTS", "Date", "resp", "now", "getTime", "warn", "rtt", "delay", "onTimeout", "info", "heartbeatInterval", "onClose", "dispose", "onAbort", "abort", "Duplex", "Event", "invariant", "log", "FRAME_LENGTH_SIZE", "Framer", "_messageCb", "undefined", "_subscribeCb", "_buffer", "_sendCallbacks", "_bytesSent", "_bytesReceived", "_writable", "drain", "_stream", "objectMode", "read", "_processResponseQueue", "write", "chunk", "encoding", "callback", "length", "Buffer", "concat", "_popFrames", "port", "send", "message", "Promise", "resolve", "frame", "encodeFrame", "push", "subscribe", "stream", "bytesSent", "bytesReceived", "writable", "responseQueue", "emit", "forEach", "cb", "offset", "decodeFrame", "bytesConsumed", "payload", "subarray", "destroy", "readableLength", "writableLength", "warn", "buffer", "frameLength", "readUInt16BE", "allocUnsafe", "writeUInt16BE", "set", "Duplex", "scheduleTaskInterval", "Event", "Trigger", "asyncTimeout", "Context", "failUndefined", "invariant", "log", "logInfo", "schema", "TimeoutError", "varint", "Event", "invariant", "log", "MAX_CHUNK_SIZE", "Balancer", "constructor", "_sysChannelId", "_lastCallerIndex", "_channels", "_framer", "Framer", "_sendBuffers", "Map", "_receiveBuffers", "_sending", "incomingData", "Event", "stream", "push", "port", "subscribe", "_processIncomingMessage", "bind", "bytesSent", "bytesReceived", "buffersCount", "size", "addChannel", "channel", "pushData", "data", "trigger", "channelId", "_enqueueChunk", "_sendChunks", "catch", "err", "log", "destroy", "info", "clear", "msg", "dataLength", "chunk", "decodeChunk", "has", "length", "set", "buffer", "Buffer", "from", "msgLength", "emit", "channelBuffer", "get", "concat", "delete", "_getNextCallerId", "index", "includes", "Error", "sendBuffer", "chunks", "idx", "subarray", "forEach", "encodeChunk", "undefined", "_getNextChunk", "shift", "writable", "drain", "waitForCount", "send", "wake", "throw", "invariant", "channelTagLength", "encodingLength", "dataLengthLength", "message", "allocUnsafe", "varint", "encode", "withLength", "decode", "offset", "bytes", "Command", "schema", "getCodecForType", "DEFAULT_SEND_COMMAND_TIMEOUT", "DESTROY_COMMAND_SEND_TIMEOUT", "STATS_INTERVAL", "MAX_SAFE_FRAME_SIZE", "SYSTEM_CHANNEL_ID", "GRACEFUL_CLOSE_TIMEOUT", "Muxer", "constructor", "_balancer", "Balancer", "_channelsByLocalId", "Map", "_channelsByTag", "_ctx", "Context", "_nextId", "_closing", "_destroying", "_disposed", "_lastStats", "undefined", "_lastChannelStats", "afterClosed", "Event", "statsUpdated", "stream", "incomingData", "on", "msg", "_handleCommand", "decode", "setSessionId", "sessionId", "_sessionId", "sessionIdString", "truncate", "createStream", "tag", "opts", "channel", "_getOrCreateStream", "contentType", "invariant", "push", "Duplex", "write", "data", "encoding", "callback", "_sendData", "then", "catch", "read", "stats", "bytesReceived", "length", "destroy", "err", "listeners", "_sendCommand", "openChannel", "id", "_destroyChannel", "createPort", "inboundBuffer", "port", "send", "timeout", "subscribe", "cb", "close", "log", "error", "message", "_dispose", "asyncTimeout", "TimeoutError", "dispose", "values", "_emitStats", "emit", "clear", "cmd", "warn", "Error", "remoteId", "buffer", "channelId", "get", "failUndefined", "trigger", "Trigger", "pushData", "encode", "wait", "params", "size", "scheduleTaskInterval", "bytesSent", "set", "addChannel", "threshold", "delete", "lastStats", "readBufferSize", "writeBufferSize", "c", "channels", "now", "Date", "interval", "timestamp", "calculateThroughput", "current", "last", "bytesSentRate", "bytesReceivedRate", "Array", "from", "map", "readableLength", "writableLength", "logInfo", "CONTROL_HEARTBEAT_INTERVAL", "CONTROL_HEARTBEAT_TIMEOUT", "Teleport", "constructor", "initiator", "localPeerId", "remotePeerId", "rest", "_ctx", "Context", "onError", "err", "destroy", "catch", "log", "error", "_muxer", "Muxer", "_extensions", "Map", "_remoteExtensions", "Set", "_open", "_destroying", "_aborting", "invariant", "PublicKey", "isPublicKey", "_control", "ControlExtension", "heartbeatInterval", "controlHeartbeatInterval", "heartbeatTimeout", "controlHeartbeatTimeout", "onTimeout", "info", "abort", "TimeoutError", "onExtensionRegistered", "set", "name", "has", "add", "_openExtension", "stream", "on", "statsUpdated", "stats", "trace", "bytesSent", "bytesSentRate", "bytesReceived", "bytesReceivedRate", "channels", "isOpen", "sessionIdString", "_sessionId", "truncate", "open", "sessionId", "random", "_setExtension", "setSessionId", "close", "disposed", "dispose", "extension", "values", "onAbort", "extensionsCount", "size", "onClose", "addExtension", "Error", "scheduleTask", "registerExtension", "RpcClosedError", "extensionName", "includes", "get", "failUndefined", "context", "createPort", "channelName", "opts", "createStream", "runInContextAsync", "onOpen", "logInfo", "synchronized", "TestBuilder", "_peers", "Set", "createPeer", "opts", "peer", "factory", "add", "createPeers", "destroy", "Promise", "all", "Array", "from", "map", "agent", "connect", "peer1", "peer2", "invariant", "has", "connection1", "createConnection", "initiator", "remotePeerId", "peerId", "connection2", "pipeStreams", "teleport", "stream", "openConnection", "disconnect", "connections", "find", "connection", "equals", "closeConnection", "TestPeer", "constructor", "PublicKey", "random", "onOpen", "onClose", "TestConnection", "open", "close", "delete", "stream1", "stream2", "pipeline", "err", "code", "log", "catch", "localPeerId", "Teleport", "whenOpen", "waitForCondition", "condition", "isOpen", "asyncTimeout", "Trigger", "invariant", "log", "schema", "createProtoRpcPeer", "TestExtension", "constructor", "callbacks", "open", "closed", "aborted", "remotePeerId", "extensionContext", "onOpen", "context", "localPeerId", "_rpc", "port", "createPort", "contentType", "requested", "TestService", "getService", "exposed", "handlers", "voidCall", "request", "testCall", "data", "timeout", "wake", "onClose", "err", "close", "onAbort", "abort", "test", "message", "wait", "res", "rpc", "closeConnection", "randomBytes", "Trigger", "invariant", "log", "schema", "createProtoRpcPeer", "TestExtensionWithStreams", "constructor", "callbacks", "open", "closed", "aborted", "_streams", "Map", "remotePeerId", "extensionContext", "_openStream", "streamTag", "interval", "chunkSize", "has", "networkStream", "createStream", "contentType", "streamEntry", "bytesSent", "bytesReceived", "sendErrors", "receiveErrors", "startTimestamp", "Date", "now", "pushChunk", "timer", "setTimeout", "chunk", "write", "err", "length", "once", "process", "nextTick", "set", "on", "data", "removeAllListeners", "reportingTimer", "setInterval", "trace", "from", "localPeerId", "to", "_closeStream", "stream", "get", "clearTimeout", "destroy", "delete", "runningTime", "onOpen", "context", "_rpc", "port", "createPort", "requested", "TestServiceWithStreams", "getService", "exposed", "handlers", "requestTestStream", "request", "streamLoadInterval", "streamLoadChunkSize", "closeTestStream", "timeout", "wake", "onClose", "Object", "entries", "close", "onAbort", "abort", "addNewStream", "wait", "toString", "rpc", "closeStream", "local", "stats", "remote", "closeConnection"]
|
7
|
+
}
|