@dxos/teleport 0.1.53-next.e9dc2bc → 0.1.54-main.270ec56

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.
Files changed (34) hide show
  1. package/dist/lib/browser/{chunk-EIJETGTE.mjs → chunk-7TGKNWZQ.mjs} +174 -55
  2. package/dist/lib/browser/chunk-7TGKNWZQ.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +202 -4
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +1 -1
  7. package/dist/lib/node/index.cjs +371 -53
  8. package/dist/lib/node/index.cjs.map +4 -4
  9. package/dist/lib/node/meta.json +1 -1
  10. package/dist/lib/node/testing/index.cjs +169 -50
  11. package/dist/lib/node/testing/index.cjs.map +4 -4
  12. package/dist/types/src/index.d.ts +1 -0
  13. package/dist/types/src/index.d.ts.map +1 -1
  14. package/dist/types/src/muxing/balancer.d.ts +23 -0
  15. package/dist/types/src/muxing/balancer.d.ts.map +1 -0
  16. package/dist/types/src/muxing/framer.d.ts +3 -0
  17. package/dist/types/src/muxing/framer.d.ts.map +1 -1
  18. package/dist/types/src/muxing/muxer.d.ts +4 -2
  19. package/dist/types/src/muxing/muxer.d.ts.map +1 -1
  20. package/dist/types/src/teleport.d.ts +2 -2
  21. package/dist/types/src/teleport.d.ts.map +1 -1
  22. package/dist/types/src/testing/test-extension-with-streams.d.ts +42 -0
  23. package/dist/types/src/testing/test-extension-with-streams.d.ts.map +1 -0
  24. package/package.json +11 -11
  25. package/src/index.ts +1 -0
  26. package/src/muxing/balancer.ts +106 -0
  27. package/src/muxing/framer.ts +20 -1
  28. package/src/muxing/muxer.test.ts +7 -7
  29. package/src/muxing/muxer.ts +95 -44
  30. package/src/rpc-extension.ts +1 -1
  31. package/src/teleport.ts +5 -5
  32. package/src/testing/test-extension-with-streams.ts +244 -0
  33. package/src/testing/test-extension.ts +4 -4
  34. package/dist/lib/browser/chunk-EIJETGTE.mjs.map +0 -7
@@ -6,6 +6,7 @@ import invariant from "tiny-invariant";
6
6
  import * as varint from "varint";
7
7
  var Framer = class {
8
8
  constructor() {
9
+ this._responseQueue = [];
9
10
  this._stream = new Duplex({
10
11
  objectMode: false,
11
12
  read: () => {
@@ -34,7 +35,14 @@ var Framer = class {
34
35
  });
35
36
  this.port = {
36
37
  send: (message) => {
37
- this._stream.push(encodeFrame(message));
38
+ return new Promise((resolve) => {
39
+ const canContinue = this._stream.push(encodeFrame(message));
40
+ if (!canContinue) {
41
+ this._responseQueue.push(resolve);
42
+ } else {
43
+ process.nextTick(resolve);
44
+ }
45
+ });
38
46
  },
39
47
  subscribe: (callback) => {
40
48
  var _a;
@@ -46,10 +54,16 @@ var Framer = class {
46
54
  };
47
55
  }
48
56
  };
57
+ this.stream.on("drain", this._processResponseQueue.bind(this));
49
58
  }
50
59
  get stream() {
51
60
  return this._stream;
52
61
  }
62
+ _processResponseQueue() {
63
+ const responseQueue = this._responseQueue;
64
+ this._responseQueue = [];
65
+ responseQueue.forEach((cb) => cb());
66
+ }
53
67
  /**
54
68
  * Attempts to pop frames from the buffer and call the message callback.
55
69
  */
@@ -70,6 +84,7 @@ var Framer = class {
70
84
  }
71
85
  }
72
86
  destroy() {
87
+ this._stream.removeAllListeners("drain");
73
88
  this._stream.destroy();
74
89
  }
75
90
  };
@@ -104,17 +119,94 @@ var encodeFrame = (payload) => {
104
119
  // packages/core/mesh/teleport/src/muxing/muxer.ts
105
120
  import { Duplex as Duplex2 } from "@dxos/node-std/stream";
106
121
  import invariant2 from "tiny-invariant";
107
- import { Event, scheduleTaskInterval } from "@dxos/async";
122
+ import { scheduleTaskInterval, Event, Trigger } from "@dxos/async";
108
123
  import { Context } from "@dxos/context";
109
124
  import { failUndefined } from "@dxos/debug";
110
125
  import { log } from "@dxos/log";
111
126
  import { schema } from "@dxos/protocols";
127
+
128
+ // packages/core/mesh/teleport/src/muxing/balancer.ts
129
+ var Balancer = class {
130
+ constructor(_port, _sysChannelId) {
131
+ this._port = _port;
132
+ this._sysChannelId = _sysChannelId;
133
+ this._lastCallerIndex = 0;
134
+ this._channels = [];
135
+ this._calls = /* @__PURE__ */ new Map();
136
+ this._channels.push(_sysChannelId);
137
+ }
138
+ addChannel(channel) {
139
+ this._channels.push(channel);
140
+ }
141
+ pushChunk(msg, trigger, channelId) {
142
+ const noCalls = this._calls.size === 0;
143
+ if (!this._channels.includes(channelId)) {
144
+ throw new Error(`Unknown channel ${channelId}`);
145
+ }
146
+ if (!this._calls.has(channelId)) {
147
+ this._calls.set(channelId, []);
148
+ }
149
+ const channelCalls = this._calls.get(channelId);
150
+ channelCalls.push({
151
+ msg,
152
+ trigger
153
+ });
154
+ if (noCalls) {
155
+ process.nextTick(async () => {
156
+ await this._processCalls();
157
+ });
158
+ }
159
+ }
160
+ destroy() {
161
+ this._calls.clear();
162
+ }
163
+ _getNextCallerId() {
164
+ if (this._calls.has(this._sysChannelId)) {
165
+ return this._sysChannelId;
166
+ }
167
+ const index = this._lastCallerIndex;
168
+ this._lastCallerIndex = (this._lastCallerIndex + 1) % this._channels.length;
169
+ return this._channels[index];
170
+ }
171
+ _getNextCall() {
172
+ let call;
173
+ while (!call) {
174
+ const channelId = this._getNextCallerId();
175
+ const channelCalls = this._calls.get(channelId);
176
+ if (!channelCalls) {
177
+ continue;
178
+ }
179
+ call = channelCalls.shift();
180
+ if (channelCalls.length === 0) {
181
+ this._calls.delete(channelId);
182
+ }
183
+ }
184
+ return call;
185
+ }
186
+ async _processCalls() {
187
+ if (this._calls.size === 0) {
188
+ return;
189
+ }
190
+ const call = this._getNextCall();
191
+ try {
192
+ await this._port.send(call.msg);
193
+ call.trigger.wake();
194
+ } catch (err) {
195
+ call.trigger.throw(err);
196
+ }
197
+ await this._processCalls();
198
+ }
199
+ };
200
+
201
+ // packages/core/mesh/teleport/src/muxing/muxer.ts
112
202
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src/muxing/muxer.ts";
113
203
  var Command = schema.getCodecForType("dxos.mesh.muxer.Command");
114
204
  var STATS_INTERVAL = 1e3;
205
+ var SYSTEM_CHANNEL_ID = -1;
115
206
  var Muxer = class {
116
207
  constructor() {
117
208
  this._framer = new Framer();
209
+ this._balancer = new Balancer(this._framer.port, SYSTEM_CHANNEL_ID);
118
210
  this.stream = this._framer.stream;
119
211
  this._channelsByLocalId = /* @__PURE__ */ new Map();
120
212
  this._channelsByTag = /* @__PURE__ */ new Map();
@@ -124,8 +216,8 @@ var Muxer = class {
124
216
  this.close = new Event();
125
217
  this.statsUpdated = new Event();
126
218
  this._ctx = new Context();
127
- this._framer.port.subscribe((msg) => {
128
- this._handleCommand(Command.decode(msg));
219
+ this._framer.port.subscribe(async (msg) => {
220
+ await this._handleCommand(Command.decode(msg));
129
221
  });
130
222
  scheduleTaskInterval(this._ctx, async () => this._emitStats(), STATS_INTERVAL);
131
223
  }
@@ -135,7 +227,7 @@ var Muxer = class {
135
227
  * The stream is immediately readable and writable.
136
228
  * NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).
137
229
  */
138
- createStream(tag, opts = {}) {
230
+ async createStream(tag, opts = {}) {
139
231
  const channel = this._getOrCreateStream({
140
232
  tag,
141
233
  contentType: opts.contentType
@@ -143,8 +235,7 @@ var Muxer = class {
143
235
  invariant2(!channel.push, `Channel already open: ${tag}`);
144
236
  const stream = new Duplex2({
145
237
  write: (data, encoding, callback) => {
146
- this._sendData(channel, data);
147
- callback();
238
+ this._sendData(channel, data).then(() => callback()).catch(callback);
148
239
  },
149
240
  read: () => {
150
241
  }
@@ -156,13 +247,18 @@ var Muxer = class {
156
247
  channel.destroy = (err) => {
157
248
  stream.destroy(err);
158
249
  };
159
- this._sendCommand({
160
- openChannel: {
161
- id: channel.id,
162
- tag: channel.tag,
163
- contentType: channel.contentType
164
- }
165
- });
250
+ try {
251
+ await this._sendCommand({
252
+ openChannel: {
253
+ id: channel.id,
254
+ tag: channel.tag,
255
+ contentType: channel.contentType
256
+ }
257
+ }, SYSTEM_CHANNEL_ID);
258
+ } catch (err) {
259
+ this._destroyChannel(channel, err);
260
+ throw err;
261
+ }
166
262
  return stream;
167
263
  }
168
264
  /**
@@ -171,7 +267,7 @@ var Muxer = class {
171
267
  * The port is immediately usable.
172
268
  * NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).
173
269
  */
174
- createPort(tag, opts = {}) {
270
+ async createPort(tag, opts = {}) {
175
271
  const channel = this._getOrCreateStream({
176
272
  tag,
177
273
  contentType: opts.contentType
@@ -188,8 +284,8 @@ var Muxer = class {
188
284
  }
189
285
  };
190
286
  const port = {
191
- send: (data) => {
192
- this._sendData(channel, data);
287
+ send: async (data) => {
288
+ await this._sendData(channel, data);
193
289
  },
194
290
  subscribe: (cb) => {
195
291
  invariant2(!callback, "Only one subscriber is allowed");
@@ -200,13 +296,18 @@ var Muxer = class {
200
296
  inboundBuffer = [];
201
297
  }
202
298
  };
203
- this._sendCommand({
204
- openChannel: {
205
- id: channel.id,
206
- tag: channel.tag,
207
- contentType: channel.contentType
208
- }
209
- });
299
+ try {
300
+ await this._sendCommand({
301
+ openChannel: {
302
+ id: channel.id,
303
+ tag: channel.tag,
304
+ contentType: channel.contentType
305
+ }
306
+ }, SYSTEM_CHANNEL_ID);
307
+ } catch (err) {
308
+ this._destroyChannel(channel, err);
309
+ throw err;
310
+ }
210
311
  return port;
211
312
  }
212
313
  /**
@@ -217,12 +318,15 @@ var Muxer = class {
217
318
  return;
218
319
  }
219
320
  this._destroying = true;
220
- this._sendCommand({
321
+ Promise.resolve(this._sendCommand({
221
322
  destroy: {
222
323
  error: err == null ? void 0 : err.message
223
324
  }
325
+ }, SYSTEM_CHANNEL_ID)).then(() => {
326
+ this._dispose();
327
+ }).catch((err2) => {
328
+ this._dispose(err2);
224
329
  });
225
- this._dispose();
226
330
  void this._ctx.dispose();
227
331
  }
228
332
  _dispose(err) {
@@ -231,6 +335,7 @@ var Muxer = class {
231
335
  return;
232
336
  }
233
337
  this._destroyed = true;
338
+ this._balancer.destroy();
234
339
  this._framer.destroy();
235
340
  for (const channel of this._channelsByTag.values()) {
236
341
  (_a = channel.destroy) == null ? void 0 : _a.call(channel, err);
@@ -239,20 +344,22 @@ var Muxer = class {
239
344
  this._channelsByLocalId.clear();
240
345
  this._channelsByTag.clear();
241
346
  }
242
- _handleCommand(cmd) {
347
+ async _handleCommand(cmd) {
243
348
  var _a;
244
349
  log("Received command", {
245
350
  cmd
246
351
  }, {
247
352
  F: __dxlog_file,
248
- L: 207,
353
+ L: 239,
249
354
  S: this,
250
355
  C: (f, a) => f(...a)
251
356
  });
252
357
  if (this._destroyed || this._destroying) {
253
- log.warn("Received command after destroy", void 0, {
358
+ log.warn("Received command after destroy", {
359
+ cmd
360
+ }, {
254
361
  F: __dxlog_file,
255
- L: 210,
362
+ L: 242,
256
363
  S: this,
257
364
  C: (f, a) => f(...a)
258
365
  });
@@ -265,12 +372,12 @@ var Muxer = class {
265
372
  });
266
373
  channel.remoteId = cmd.openChannel.id;
267
374
  for (const data of channel.buffer) {
268
- this._sendCommand({
375
+ await this._sendCommand({
269
376
  data: {
270
377
  channelId: channel.remoteId,
271
378
  data
272
379
  }
273
- });
380
+ }, channel.id);
274
381
  }
275
382
  channel.buffer = [];
276
383
  } else if (cmd.data) {
@@ -280,7 +387,7 @@ var Muxer = class {
280
387
  tag: stream.tag
281
388
  }, {
282
389
  F: __dxlog_file,
283
- L: 234,
390
+ L: 269,
284
391
  S: this,
285
392
  C: (f, a) => f(...a)
286
393
  });
@@ -291,10 +398,14 @@ var Muxer = class {
291
398
  this._dispose();
292
399
  }
293
400
  }
294
- _sendCommand(cmd) {
295
- Promise.resolve(this._framer.port.send(Command.encode(cmd))).catch((err) => {
401
+ async _sendCommand(cmd, channelId = -1) {
402
+ try {
403
+ const trigger = new Trigger();
404
+ this._balancer.pushChunk(Command.encode(cmd), trigger, channelId);
405
+ await trigger.wait();
406
+ } catch (err) {
296
407
  this.destroy(err);
297
- });
408
+ }
298
409
  }
299
410
  _getOrCreateStream(params) {
300
411
  let channel = this._channelsByTag.get(params.tag);
@@ -314,21 +425,29 @@ var Muxer = class {
314
425
  };
315
426
  this._channelsByTag.set(channel.tag, channel);
316
427
  this._channelsByLocalId.set(channel.id, channel);
428
+ this._balancer.addChannel(channel.id);
317
429
  }
318
430
  return channel;
319
431
  }
320
- _sendData(channel, data) {
432
+ async _sendData(channel, data) {
321
433
  channel.stats.bytesSent += data.length;
322
434
  if (channel.remoteId === null) {
323
435
  channel.buffer.push(data);
324
- } else {
325
- this._sendCommand({
326
- data: {
327
- channelId: channel.remoteId,
328
- data
329
- }
330
- });
436
+ return;
437
+ }
438
+ await this._sendCommand({
439
+ data: {
440
+ channelId: channel.remoteId,
441
+ data
442
+ }
443
+ }, channel.id);
444
+ }
445
+ _destroyChannel(channel, err) {
446
+ if (channel.destroy) {
447
+ channel.destroy(err);
331
448
  }
449
+ this._channelsByLocalId.delete(channel.id);
450
+ this._channelsByTag.delete(channel.tag);
332
451
  }
333
452
  async _emitStats() {
334
453
  if (this._destroyed || this._destroying) {
@@ -514,11 +633,11 @@ var Teleport = class {
514
633
  initiator: this.initiator,
515
634
  localPeerId: this.localPeerId,
516
635
  remotePeerId: this.remotePeerId,
517
- createPort: (channelName, opts) => {
636
+ createPort: async (channelName, opts) => {
518
637
  invariant3(!channelName.includes("/"), "Invalid channel name");
519
638
  return this._muxer.createPort(`${extensionName}/${channelName}`, opts);
520
639
  },
521
- createStream: (channelName, opts) => {
640
+ createStream: async (channelName, opts) => {
522
641
  invariant3(!channelName.includes("/"), "Invalid channel name");
523
642
  return this._muxer.createStream(`${extensionName}/${channelName}`, opts);
524
643
  },
@@ -570,7 +689,7 @@ var ControlExtension = class {
570
689
  }
571
690
  }
572
691
  },
573
- port: extensionContext.createPort("rpc", {
692
+ port: await extensionContext.createPort("rpc", {
574
693
  contentType: 'application/x-protobuf; messagType="dxos.rpc.Message"'
575
694
  })
576
695
  });
@@ -596,7 +715,7 @@ var ControlExtension = class {
596
715
 
597
716
  // packages/core/mesh/teleport/src/testing/test-extension.ts
598
717
  import invariant4 from "tiny-invariant";
599
- import { asyncTimeout as asyncTimeout2, Trigger } from "@dxos/async";
718
+ import { asyncTimeout as asyncTimeout2, Trigger as Trigger2 } from "@dxos/async";
600
719
  import { log as log3 } from "@dxos/log";
601
720
  import { schema as schema3 } from "@dxos/protocols";
602
721
  import { createProtoRpcPeer as createProtoRpcPeer2 } from "@dxos/rpc";
@@ -604,8 +723,8 @@ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/mesh/teleport/src
604
723
  var TestExtension = class {
605
724
  constructor(callbacks = {}) {
606
725
  this.callbacks = callbacks;
607
- this.open = new Trigger();
608
- this.closed = new Trigger();
726
+ this.open = new Trigger2();
727
+ this.closed = new Trigger2();
609
728
  }
610
729
  get remotePeerId() {
611
730
  var _a;
@@ -624,7 +743,7 @@ var TestExtension = class {
624
743
  });
625
744
  this.extensionContext = context;
626
745
  this._rpc = createProtoRpcPeer2({
627
- port: context.createPort("rpc", {
746
+ port: await context.createPort("rpc", {
628
747
  contentType: 'application/x-protobuf; messageType="dxos.rpc.Message"'
629
748
  }),
630
749
  requested: {
@@ -644,7 +763,7 @@ var TestExtension = class {
644
763
  }
645
764
  }
646
765
  },
647
- timeout: 1e3
766
+ timeout: 2e3
648
767
  });
649
768
  await this._rpc.open();
650
769
  await ((_b = (_a = this.callbacks).onOpen) == null ? void 0 : _b.call(_a));
@@ -666,11 +785,11 @@ var TestExtension = class {
666
785
  }
667
786
  async test(message = "test") {
668
787
  await this.open.wait({
669
- timeout: 500
788
+ timeout: 1500
670
789
  });
671
790
  const res = await asyncTimeout2(this._rpc.rpc.TestService.testCall({
672
791
  data: message
673
- }), 500);
792
+ }), 1500);
674
793
  invariant4(res.data === message);
675
794
  }
676
795
  /**
@@ -690,4 +809,4 @@ export {
690
809
  Teleport,
691
810
  TestExtension
692
811
  };
693
- //# sourceMappingURL=chunk-EIJETGTE.mjs.map
812
+ //# sourceMappingURL=chunk-7TGKNWZQ.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/muxing/framer.ts", "../../../src/muxing/muxer.ts", "../../../src/muxing/balancer.ts", "../../../src/teleport.ts", "../../../src/testing/test-extension.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { Duplex } from 'node:stream';\nimport invariant from 'tiny-invariant';\nimport * as varint from 'varint';\n\nimport { RpcPort } from './rpc-port';\n\n/**\n * Framer that turns a stream of binary messages into a framed RpcPort.\n *\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;\n private _subscribeCb?: () => void;\n private _buffer?: Buffer; // The rest of the bytes from the previous write call.\n private _responseQueue: (() => void)[] = [];\n\n private readonly _stream = new Duplex({\n objectMode: false,\n read: () => {},\n write: (chunk, encoding, callback) => {\n invariant(!this._subscribeCb, 'Internal Framer bug. Concurrent writes detected.');\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 canContinue = this._stream.push(encodeFrame(message));\n if (!canContinue) {\n this._responseQueue.push(resolve);\n } else {\n process.nextTick(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 constructor() {\n this.stream.on('drain', this._processResponseQueue.bind(this));\n }\n\n private _processResponseQueue() {\n const responseQueue = this._responseQueue;\n this._responseQueue = [];\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 this._stream.removeAllListeners('drain');\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 try {\n const frameLength = varint.decode(buffer, offset);\n const tagLength = varint.decode.bytes;\n\n if (buffer.length < offset + tagLength + frameLength) {\n // Not enough bytes to read the frame.\n return undefined;\n }\n\n const payload = buffer.subarray(offset + tagLength, offset + tagLength + frameLength);\n\n return {\n payload,\n bytesConsumed: tagLength + frameLength,\n };\n } catch (err) {\n if (err instanceof RangeError) {\n // Not enough bytes to read the tag.\n return undefined;\n } else {\n throw err;\n }\n }\n};\n\nexport const encodeFrame = (payload: Uint8Array): Buffer => {\n const tagLength = varint.encodingLength(payload.length);\n const frame = Buffer.allocUnsafe(tagLength + payload.length);\n varint.encode(payload.length, frame);\n frame.set(payload, tagLength);\n return frame;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Duplex } from 'node:stream';\nimport invariant from 'tiny-invariant';\n\nimport { scheduleTaskInterval, Event, Trigger } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { failUndefined } from '@dxos/debug';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { ConnectionInfo } from '@dxos/protocols/proto/dxos/devtools/swarm';\nimport { Command } from '@dxos/protocols/proto/dxos/mesh/muxer';\n\nimport { Balancer } from './balancer';\nimport { Framer } from './framer';\nimport { RpcPort } from './rpc-port';\n\nconst Command = schema.getCodecForType('dxos.mesh.muxer.Command');\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\nconst STATS_INTERVAL = 1000;\n\nconst SYSTEM_CHANNEL_ID = -1;\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 _framer = new Framer();\n private readonly _balancer = new Balancer(this._framer.port, SYSTEM_CHANNEL_ID);\n public readonly stream = this._framer.stream;\n\n private readonly _channelsByLocalId = new Map<number, Channel>();\n private readonly _channelsByTag = new Map<string, Channel>();\n\n private _nextId = 0;\n private _destroyed = false;\n private _destroying = false;\n\n public close = new Event<Error | undefined>();\n\n public statsUpdated = new Event<ConnectionInfo.StreamStats[]>();\n\n private readonly _ctx = new Context();\n\n constructor() {\n // Add a channel for control messages.\n this._framer.port.subscribe(async (msg) => {\n await this._handleCommand(Command.decode(msg));\n });\n\n scheduleTaskInterval(this._ctx, async () => this._emitStats(), STATS_INTERVAL);\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 stream.destroy(err);\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) => {\n await this._sendData(channel, data);\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 /**\n * Force-close with optional error.\n */\n destroy(err?: Error) {\n if (this._destroying) {\n return;\n }\n this._destroying = true;\n\n Promise.resolve(\n this._sendCommand(\n {\n destroy: {\n error: err?.message,\n },\n },\n SYSTEM_CHANNEL_ID,\n ),\n )\n .then(() => {\n this._dispose();\n })\n .catch((err: any) => {\n this._dispose(err);\n });\n void this._ctx.dispose();\n }\n\n private _dispose(err?: Error) {\n if (this._destroyed) {\n return;\n }\n\n this._destroyed = true;\n this._balancer.destroy();\n this._framer.destroy();\n\n for (const channel of this._channelsByTag.values()) {\n channel.destroy?.(err);\n }\n\n this.close.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 log('Received command', { cmd });\n\n if (this._destroyed || this._destroying) {\n log.warn('Received command after destroy', { cmd });\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 } else if (cmd.destroy) {\n this._dispose();\n }\n }\n\n private async _sendCommand(cmd: Command, channelId = -1) {\n try {\n const trigger = new Trigger<void>();\n this._balancer.pushChunk(Command.encode(cmd), trigger, channelId);\n await trigger.wait();\n } catch (err: any) {\n this.destroy(err);\n }\n }\n\n private _getOrCreateStream(params: CreateChannelInternalParams): Channel {\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 return channel;\n }\n\n private async _sendData(channel: Channel, data: Uint8Array): Promise<void> {\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 );\n }\n\n private _destroyChannel(channel: Channel, err?: Error) {\n if (channel.destroy) {\n channel.destroy(err);\n }\n this._channelsByLocalId.delete(channel.id);\n this._channelsByTag.delete(channel.tag);\n }\n\n private async _emitStats() {\n if (this._destroyed || this._destroying) {\n return;\n }\n\n this.statsUpdated.emit(\n Array.from(this._channelsByTag.values()).map((channel) => ({\n id: channel.id,\n tag: channel.tag,\n bytesSent: channel.stats.bytesSent,\n bytesReceived: channel.stats.bytesReceived,\n })),\n );\n }\n}\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// Copyright 2023 DXOS.org\n//\n\nimport { Trigger } from '@dxos/async';\n\n// TODO(egorgripasov): Is BinaryPort a better name?\nimport { RpcPort } from './rpc-port';\n\ntype Chunk = {\n msg: Uint8Array;\n trigger: Trigger;\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 // TODO(egorgripasov): Will cause a memory leak if channels do not appreciate the backpressure.\n private _calls: Map<number, Chunk[]> = new Map();\n\n constructor(private readonly _port: RpcPort, private readonly _sysChannelId: number) {\n this._channels.push(_sysChannelId);\n }\n\n addChannel(channel: number) {\n this._channels.push(channel);\n }\n\n pushChunk(msg: Uint8Array, trigger: Trigger, channelId: number) {\n const noCalls = this._calls.size === 0;\n\n if (!this._channels.includes(channelId)) {\n throw new Error(`Unknown channel ${channelId}`);\n }\n\n if (!this._calls.has(channelId)) {\n this._calls.set(channelId, []);\n }\n\n const channelCalls = this._calls.get(channelId)!;\n channelCalls.push({ msg, trigger });\n\n // Start processing calls if this is the first call.\n if (noCalls) {\n process.nextTick(async () => {\n await this._processCalls();\n });\n }\n }\n\n destroy() {\n this._calls.clear();\n }\n\n private _getNextCallerId() {\n if (this._calls.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 _getNextCall(): Chunk {\n let call;\n while (!call) {\n const channelId = this._getNextCallerId();\n const channelCalls = this._calls.get(channelId);\n if (!channelCalls) {\n continue;\n }\n\n call = channelCalls.shift();\n if (channelCalls.length === 0) {\n this._calls.delete(channelId);\n }\n }\n return call;\n }\n\n private async _processCalls() {\n if (this._calls.size === 0) {\n return;\n }\n\n const call = this._getNextCall();\n\n try {\n await this._port.send(call.msg);\n call.trigger.wake();\n } catch (err: any) {\n call.trigger.throw(err);\n }\n\n await this._processCalls();\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Duplex } from 'node:stream';\nimport invariant from 'tiny-invariant';\n\nimport { asyncTimeout, scheduleTaskInterval, runInContextAsync, synchronized, scheduleTask, Event } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { failUndefined } from '@dxos/debug';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { schema, RpcClosedError } from '@dxos/protocols';\nimport { ConnectionInfo } from '@dxos/protocols/proto/dxos/devtools/swarm';\nimport { ControlService } from '@dxos/protocols/proto/dxos/mesh/teleport/control';\nimport { createProtoRpcPeer, ProtoRpcPeer } from '@dxos/rpc';\nimport { Callback } from '@dxos/util';\n\nimport { CreateChannelOpts, Muxer, RpcPort } from './muxing';\n\nexport type TeleportParams = {\n initiator: boolean;\n localPeerId: PublicKey;\n remotePeerId: PublicKey;\n};\n\nexport class Teleport {\n public readonly initiator: boolean;\n public readonly localPeerId: PublicKey;\n public readonly remotePeerId: 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 = new ControlExtension({\n heartbeatInterval: 10_000,\n heartbeatTimeout: 10_000,\n onTimeout: () => {\n this.destroy(new Error('Connection timed out')).catch((err) => log.catch(err));\n },\n });\n\n private readonly _extensions = new Map<string, TeleportExtension>();\n private readonly _remoteExtensions = new Set<string>();\n\n private _open = false;\n\n constructor({ initiator, localPeerId, remotePeerId }: TeleportParams) {\n invariant(typeof initiator === 'boolean');\n invariant(PublicKey.isPublicKey(localPeerId));\n invariant(PublicKey.isPublicKey(remotePeerId));\n invariant(typeof initiator === 'boolean');\n this.initiator = initiator;\n this.localPeerId = localPeerId;\n this.remotePeerId = remotePeerId;\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 await this.destroy();\n });\n\n this._muxer.stream.on('error', async (err) => {\n await this.destroy(err);\n });\n }\n }\n\n get stream(): Duplex {\n return this._muxer.stream;\n }\n\n get stats(): Event<ConnectionInfo.StreamStats[]> {\n return this._muxer.statsUpdated;\n }\n\n /**\n * Blocks until the handshake is complete.\n */\n async open() {\n this._setExtension('dxos.mesh.teleport.control', this._control);\n await this._openExtension('dxos.mesh.teleport.control');\n this._open = true;\n }\n\n async close(err?: Error) {\n // TODO(dmaretskyi): Try soft close.\n\n await this.destroy(err);\n }\n\n @synchronized\n async destroy(err?: Error) {\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.onClose(err);\n } catch (err: any) {\n log.catch(err);\n }\n }\n\n this._muxer.destroy(err);\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}\n\ntype ControlExtensionOpts = {\n heartbeatInterval: number;\n heartbeatTimeout: number;\n onTimeout: () => void;\n};\n\nclass ControlExtension implements TeleportExtension {\n private readonly _ctx = new Context({\n onError: (err) => {\n this._extensionContext.close(err);\n },\n });\n\n private _extensionContext!: ExtensionContext;\n private _rpc!: ProtoRpcPeer<{ Control: ControlService }>;\n\n public readonly onExtensionRegistered = new Callback<(extensionName: string) => void>();\n\n constructor(private readonly opts: ControlExtensionOpts) {}\n\n async onOpen(extensionContext: ExtensionContext): Promise<void> {\n this._extensionContext = extensionContext;\n\n // NOTE: Make sure that RPC timeout is greater than the heartbeat timeout.\n // TODO(dmaretskyi): Allow overwriting the timeout on individual RPC calls?\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 // Ok.\n },\n },\n },\n port: await extensionContext.createPort('rpc', {\n contentType: 'application/x-protobuf; messagType=\"dxos.rpc.Message\"',\n }),\n });\n\n await this._rpc.open();\n\n scheduleTaskInterval(\n this._ctx,\n async () => {\n try {\n await asyncTimeout(this._rpc.rpc.Control.heartbeat(), this.opts.heartbeatTimeout);\n } catch (err: any) {\n this.opts.onTimeout();\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 registerExtension(name: string) {\n await this._rpc.rpc.Control.registerExtension({ name });\n }\n}\n\ntype ControlRpcBundle = {\n Control: ControlService;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport invariant from 'tiny-invariant';\n\nimport { asyncTimeout, Trigger } from '@dxos/async';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { TestService } from '@dxos/protocols/proto/example/testing/rpc';\nimport { createProtoRpcPeer, ProtoRpcPeer } from '@dxos/rpc';\n\nimport { ExtensionContext, TeleportExtension } from '../teleport';\n\ninterface TestExtensionCallbacks {\n onOpen?: () => Promise<void>;\n onClose?: () => Promise<void>;\n}\n\nexport class TestExtension implements TeleportExtension {\n public readonly open = new Trigger();\n public readonly closed = 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 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"],
5
+ "mappings": "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",
6
+ "names": ["Duplex", "invariant", "varint", "Framer", "constructor", "_responseQueue", "_stream", "Duplex", "objectMode", "read", "write", "chunk", "encoding", "callback", "invariant", "_subscribeCb", "_buffer", "length", "Buffer", "concat", "_messageCb", "_popFrames", "undefined", "port", "send", "message", "Promise", "resolve", "canContinue", "push", "encodeFrame", "process", "nextTick", "subscribe", "stream", "on", "_processResponseQueue", "bind", "responseQueue", "forEach", "cb", "offset", "frame", "decodeFrame", "bytesConsumed", "payload", "subarray", "destroy", "removeAllListeners", "buffer", "frameLength", "decode", "tagLength", "bytes", "err", "RangeError", "encodingLength", "allocUnsafe", "varint", "encode", "set", "Duplex", "invariant", "scheduleTaskInterval", "Event", "Trigger", "Context", "failUndefined", "log", "schema", "Balancer", "constructor", "_port", "_sysChannelId", "_lastCallerIndex", "_channels", "_calls", "Map", "push", "addChannel", "channel", "pushChunk", "msg", "trigger", "channelId", "noCalls", "size", "includes", "Error", "has", "set", "channelCalls", "get", "process", "nextTick", "_processCalls", "destroy", "clear", "_getNextCallerId", "index", "length", "_getNextCall", "call", "shift", "delete", "send", "wake", "err", "throw", "Command", "schema", "getCodecForType", "STATS_INTERVAL", "SYSTEM_CHANNEL_ID", "Muxer", "constructor", "_framer", "Framer", "_balancer", "Balancer", "port", "stream", "_channelsByLocalId", "Map", "_channelsByTag", "_nextId", "_destroyed", "_destroying", "close", "Event", "statsUpdated", "_ctx", "Context", "subscribe", "msg", "_handleCommand", "decode", "scheduleTaskInterval", "_emitStats", "createStream", "tag", "opts", "channel", "_getOrCreateStream", "contentType", "invariant", "push", "Duplex", "write", "data", "encoding", "callback", "_sendData", "then", "catch", "read", "stats", "bytesReceived", "length", "destroy", "err", "_sendCommand", "openChannel", "id", "_destroyChannel", "createPort", "inboundBuffer", "send", "cb", "Promise", "resolve", "error", "message", "_dispose", "dispose", "values", "emit", "clear", "cmd", "log", "warn", "remoteId", "buffer", "channelId", "get", "failUndefined", "trigger", "Trigger", "pushChunk", "encode", "wait", "params", "bytesSent", "set", "addChannel", "delete", "Array", "from", "map", "invariant", "asyncTimeout", "scheduleTaskInterval", "runInContextAsync", "synchronized", "scheduleTask", "Context", "failUndefined", "PublicKey", "log", "schema", "RpcClosedError", "createProtoRpcPeer", "Callback", "Teleport", "constructor", "initiator", "localPeerId", "remotePeerId", "_ctx", "Context", "onError", "err", "destroy", "catch", "log", "error", "_muxer", "Muxer", "_control", "ControlExtension", "heartbeatInterval", "heartbeatTimeout", "onTimeout", "Error", "_extensions", "Map", "_remoteExtensions", "Set", "_open", "invariant", "PublicKey", "isPublicKey", "onExtensionRegistered", "set", "name", "has", "add", "_openExtension", "stream", "on", "stats", "statsUpdated", "open", "_setExtension", "close", "disposed", "dispose", "extension", "values", "onClose", "addExtension", "scheduleTask", "registerExtension", "RpcClosedError", "extensionName", "includes", "get", "failUndefined", "context", "createPort", "channelName", "opts", "createStream", "runInContextAsync", "onOpen", "synchronized", "_extensionContext", "Callback", "extensionContext", "_rpc", "createProtoRpcPeer", "requested", "Control", "schema", "getService", "exposed", "handlers", "request", "call", "heartbeat", "port", "contentType", "scheduleTaskInterval", "asyncTimeout", "rpc", "invariant", "asyncTimeout", "Trigger", "log", "schema", "createProtoRpcPeer", "TestExtension", "constructor", "callbacks", "open", "closed", "remotePeerId", "extensionContext", "onOpen", "context", "localPeerId", "_rpc", "port", "createPort", "contentType", "requested", "TestService", "getService", "exposed", "handlers", "voidCall", "request", "testCall", "data", "timeout", "wake", "onClose", "err", "close", "test", "message", "wait", "res", "rpc", "closeConnection"]
7
+ }