@dxos/teleport 0.1.17 → 0.1.19
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/index.mjs +161 -20
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{testing.mjs → testing/index.mjs} +103 -23
- package/dist/lib/browser/testing/index.mjs.map +7 -0
- package/dist/lib/node/index.cjs +165 -21
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{testing.cjs → testing/index.cjs} +106 -23
- package/dist/lib/node/testing/index.cjs.map +7 -0
- package/dist/types/src/index.d.ts +2 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/muxing/framer.d.ts +2 -1
- package/dist/types/src/muxing/framer.d.ts.map +1 -1
- package/dist/types/src/rpc-extension.d.ts +17 -0
- package/dist/types/src/rpc-extension.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +3 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/{testing.d.ts → testing/test-builder.d.ts} +2 -2
- package/dist/types/src/testing/test-builder.d.ts.map +1 -0
- package/dist/types/src/testing/test-extension.d.ts +20 -0
- package/dist/types/src/testing/test-extension.d.ts.map +1 -0
- package/package.json +10 -10
- package/src/index.ts +2 -0
- package/src/muxing/framer.test.ts +9 -8
- package/src/muxing/framer.ts +11 -10
- package/src/rpc-extension.ts +63 -0
- package/src/teleport.test.ts +1 -1
- package/src/testing/index.ts +6 -0
- package/src/{testing.ts → testing/test-builder.ts} +1 -1
- package/src/{test-extension.ts → testing/test-extension.ts} +18 -5
- package/testing.js +1 -1
- package/dist/lib/browser/testing.mjs.map +0 -7
- package/dist/lib/node/testing.cjs.map +0 -7
- package/dist/types/src/test-extension.d.ts +0 -12
- package/dist/types/src/test-extension.d.ts.map +0 -1
- package/dist/types/src/testing.d.ts.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "@dxos/node-std/globals"
|
|
2
2
|
|
|
3
|
-
// packages/core/mesh/teleport/src/testing.ts
|
|
3
|
+
// packages/core/mesh/teleport/src/testing/test-builder.ts
|
|
4
4
|
import { pipeline } from "@dxos/node-std/stream";
|
|
5
5
|
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
6
6
|
import { log as log3 } from "@dxos/log";
|
|
@@ -50,8 +50,7 @@ var Framer = class {
|
|
|
50
50
|
});
|
|
51
51
|
this.port = {
|
|
52
52
|
send: (message) => {
|
|
53
|
-
this._stream.push(
|
|
54
|
-
this._stream.push(message);
|
|
53
|
+
this._stream.push(encodeFrame(message));
|
|
55
54
|
},
|
|
56
55
|
subscribe: (callback) => {
|
|
57
56
|
var _a;
|
|
@@ -70,7 +69,7 @@ var Framer = class {
|
|
|
70
69
|
_popFrames() {
|
|
71
70
|
let offset = 0;
|
|
72
71
|
while (offset < this._buffer.length) {
|
|
73
|
-
const frame =
|
|
72
|
+
const frame = decodeFrame(this._buffer, offset);
|
|
74
73
|
if (!frame) {
|
|
75
74
|
break;
|
|
76
75
|
}
|
|
@@ -87,7 +86,7 @@ var Framer = class {
|
|
|
87
86
|
this._stream.destroy();
|
|
88
87
|
}
|
|
89
88
|
};
|
|
90
|
-
var
|
|
89
|
+
var decodeFrame = (buffer, offset) => {
|
|
91
90
|
try {
|
|
92
91
|
const frameLength = varint.decode(buffer, offset);
|
|
93
92
|
const tagLength = varint.decode.bytes;
|
|
@@ -107,12 +106,12 @@ var readFrame = (buffer, offset) => {
|
|
|
107
106
|
}
|
|
108
107
|
}
|
|
109
108
|
};
|
|
110
|
-
var
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return
|
|
109
|
+
var encodeFrame = (payload) => {
|
|
110
|
+
const tagLength = varint.encodingLength(payload.length);
|
|
111
|
+
const frame = Buffer.allocUnsafe(tagLength + payload.length);
|
|
112
|
+
varint.encode(payload.length, frame);
|
|
113
|
+
frame.set(payload, tagLength);
|
|
114
|
+
return frame;
|
|
116
115
|
};
|
|
117
116
|
|
|
118
117
|
// packages/core/mesh/teleport/src/muxing/muxer.ts
|
|
@@ -234,14 +233,14 @@ var Muxer = class {
|
|
|
234
233
|
log("Received command", {
|
|
235
234
|
cmd
|
|
236
235
|
}, {
|
|
237
|
-
file: "
|
|
236
|
+
file: "muxer.ts",
|
|
238
237
|
line: 194,
|
|
239
238
|
scope: this,
|
|
240
239
|
callSite: (f, a) => f(...a)
|
|
241
240
|
});
|
|
242
241
|
if (this._destroyed || this._destroying) {
|
|
243
242
|
log.warn("Received command after destroy", {}, {
|
|
244
|
-
file: "
|
|
243
|
+
file: "muxer.ts",
|
|
245
244
|
line: 197,
|
|
246
245
|
scope: this,
|
|
247
246
|
callSite: (f, a) => f(...a)
|
|
@@ -269,7 +268,7 @@ var Muxer = class {
|
|
|
269
268
|
log.warn("Received data for channel before it was opened", {
|
|
270
269
|
tag: stream.tag
|
|
271
270
|
}, {
|
|
272
|
-
file: "
|
|
271
|
+
file: "muxer.ts",
|
|
273
272
|
line: 221,
|
|
274
273
|
scope: this,
|
|
275
274
|
callSite: (f, a) => f(...a)
|
|
@@ -334,7 +333,7 @@ var Teleport = class {
|
|
|
334
333
|
onError: (err) => {
|
|
335
334
|
void this.destroy(err).catch(() => {
|
|
336
335
|
log2.error("Error during destroy", err, {
|
|
337
|
-
file: "
|
|
336
|
+
file: "teleport.ts",
|
|
338
337
|
line: 34,
|
|
339
338
|
scope: this,
|
|
340
339
|
callSite: (f, a) => f(...a)
|
|
@@ -361,7 +360,7 @@ var Teleport = class {
|
|
|
361
360
|
log2("remote extension", {
|
|
362
361
|
name
|
|
363
362
|
}, {
|
|
364
|
-
file: "
|
|
363
|
+
file: "teleport.ts",
|
|
365
364
|
line: 61,
|
|
366
365
|
scope: this,
|
|
367
366
|
callSite: (f, a) => f(...a)
|
|
@@ -406,7 +405,7 @@ var Teleport = class {
|
|
|
406
405
|
await extension.onClose(err);
|
|
407
406
|
} catch (err1) {
|
|
408
407
|
log2.catch(err1, {}, {
|
|
409
|
-
file: "
|
|
408
|
+
file: "teleport.ts",
|
|
410
409
|
line: 117,
|
|
411
410
|
scope: this,
|
|
412
411
|
callSite: (f, a) => f(...a)
|
|
@@ -422,7 +421,7 @@ var Teleport = class {
|
|
|
422
421
|
log2("addExtension", {
|
|
423
422
|
name
|
|
424
423
|
}, {
|
|
425
|
-
file: "
|
|
424
|
+
file: "teleport.ts",
|
|
426
425
|
line: 129,
|
|
427
426
|
scope: this,
|
|
428
427
|
callSite: (f, a) => f(...a)
|
|
@@ -454,7 +453,7 @@ var Teleport = class {
|
|
|
454
453
|
log2("open extension", {
|
|
455
454
|
extensionName
|
|
456
455
|
}, {
|
|
457
|
-
file: "
|
|
456
|
+
file: "teleport.ts",
|
|
458
457
|
line: 159,
|
|
459
458
|
scope: this,
|
|
460
459
|
callSite: (f, a) => f(...a)
|
|
@@ -482,7 +481,7 @@ var Teleport = class {
|
|
|
482
481
|
log2("extension opened", {
|
|
483
482
|
extensionName
|
|
484
483
|
}, {
|
|
485
|
-
file: "
|
|
484
|
+
file: "teleport.ts",
|
|
486
485
|
line: 182,
|
|
487
486
|
scope: this,
|
|
488
487
|
callSite: (f, a) => f(...a)
|
|
@@ -545,7 +544,7 @@ var ControlExtension = class {
|
|
|
545
544
|
}
|
|
546
545
|
};
|
|
547
546
|
|
|
548
|
-
// packages/core/mesh/teleport/src/testing.ts
|
|
547
|
+
// packages/core/mesh/teleport/src/testing/test-builder.ts
|
|
549
548
|
var TestBuilder = class {
|
|
550
549
|
constructor() {
|
|
551
550
|
this._peers = new Array();
|
|
@@ -603,7 +602,7 @@ var TestPeer = class {
|
|
|
603
602
|
pipeline(this.teleport.stream, peer.teleport.stream, (err) => {
|
|
604
603
|
if (err && err.code !== "ERR_STREAM_PREMATURE_CLOSE") {
|
|
605
604
|
log3.catch(err, {}, {
|
|
606
|
-
file: "
|
|
605
|
+
file: "test-builder.ts",
|
|
607
606
|
line: 67,
|
|
608
607
|
scope: this,
|
|
609
608
|
callSite: (f, a) => f(...a)
|
|
@@ -616,8 +615,89 @@ var TestPeer = class {
|
|
|
616
615
|
await ((_a = this.teleport) == null ? void 0 : _a.destroy());
|
|
617
616
|
}
|
|
618
617
|
};
|
|
618
|
+
|
|
619
|
+
// packages/core/mesh/teleport/src/testing/test-extension.ts
|
|
620
|
+
import assert4 from "@dxos/node-std/assert";
|
|
621
|
+
import { asyncTimeout as asyncTimeout2, Trigger } from "@dxos/async";
|
|
622
|
+
import { log as log4 } from "@dxos/log";
|
|
623
|
+
import { schema as schema3 } from "@dxos/protocols";
|
|
624
|
+
import { createProtoRpcPeer as createProtoRpcPeer2 } from "@dxos/rpc";
|
|
625
|
+
var TestExtension = class {
|
|
626
|
+
constructor(callbacks = {}) {
|
|
627
|
+
this.callbacks = callbacks;
|
|
628
|
+
this.open = new Trigger();
|
|
629
|
+
this.closed = new Trigger();
|
|
630
|
+
}
|
|
631
|
+
get remotePeerId() {
|
|
632
|
+
var _a;
|
|
633
|
+
return (_a = this.extensionContext) == null ? void 0 : _a.remotePeerId;
|
|
634
|
+
}
|
|
635
|
+
async onOpen(context) {
|
|
636
|
+
var _a, _b;
|
|
637
|
+
log4("onOpen", {
|
|
638
|
+
localPeerId: context.localPeerId,
|
|
639
|
+
remotePeerId: context.remotePeerId
|
|
640
|
+
}, {
|
|
641
|
+
file: "test-extension.ts",
|
|
642
|
+
line: 33,
|
|
643
|
+
scope: this,
|
|
644
|
+
callSite: (f, a) => f(...a)
|
|
645
|
+
});
|
|
646
|
+
this.extensionContext = context;
|
|
647
|
+
this._rpc = createProtoRpcPeer2({
|
|
648
|
+
port: context.createPort("rpc", {
|
|
649
|
+
contentType: 'application/x-protobuf; messageType="dxos.rpc.Message"'
|
|
650
|
+
}),
|
|
651
|
+
requested: {
|
|
652
|
+
TestService: schema3.getService("example.testing.rpc.TestService")
|
|
653
|
+
},
|
|
654
|
+
exposed: {
|
|
655
|
+
TestService: schema3.getService("example.testing.rpc.TestService")
|
|
656
|
+
},
|
|
657
|
+
handlers: {
|
|
658
|
+
TestService: {
|
|
659
|
+
voidCall: async (request) => {
|
|
660
|
+
},
|
|
661
|
+
testCall: async (request) => {
|
|
662
|
+
return {
|
|
663
|
+
data: request.data
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
timeout: 1e3
|
|
669
|
+
});
|
|
670
|
+
await this._rpc.open();
|
|
671
|
+
await ((_b = (_a = this.callbacks).onOpen) == null ? void 0 : _b.call(_a));
|
|
672
|
+
this.open.wake();
|
|
673
|
+
}
|
|
674
|
+
async onClose(err) {
|
|
675
|
+
var _a, _b, _c;
|
|
676
|
+
log4("onClose", {
|
|
677
|
+
err
|
|
678
|
+
}, {
|
|
679
|
+
file: "test-extension.ts",
|
|
680
|
+
line: 67,
|
|
681
|
+
scope: this,
|
|
682
|
+
callSite: (f, a) => f(...a)
|
|
683
|
+
});
|
|
684
|
+
await ((_b = (_a = this.callbacks).onClose) == null ? void 0 : _b.call(_a));
|
|
685
|
+
this.closed.wake();
|
|
686
|
+
await ((_c = this._rpc) == null ? void 0 : _c.close());
|
|
687
|
+
}
|
|
688
|
+
async test() {
|
|
689
|
+
await this.open.wait({
|
|
690
|
+
timeout: 500
|
|
691
|
+
});
|
|
692
|
+
const res = await asyncTimeout2(this._rpc.rpc.TestService.testCall({
|
|
693
|
+
data: "test"
|
|
694
|
+
}), 500);
|
|
695
|
+
assert4(res.data === "test");
|
|
696
|
+
}
|
|
697
|
+
};
|
|
619
698
|
export {
|
|
620
699
|
TestBuilder,
|
|
700
|
+
TestExtension,
|
|
621
701
|
TestPeer
|
|
622
702
|
};
|
|
623
|
-
//# sourceMappingURL=
|
|
703
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/testing/test-builder.ts", "../../../../src/teleport.ts", "../../../../src/muxing/framer.ts", "../../../../src/muxing/muxer.ts", "../../../../src/testing/test-extension.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { pipeline } from 'node:stream';\n\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { Teleport } from '../teleport';\n\nexport class TestBuilder {\n private readonly _peers = new Array<TestPeer>();\n\n createPeer(peerId?: PublicKey): TestPeer {\n const peer = new TestPeer(peerId);\n this._peers.push(peer);\n return peer;\n }\n\n async destroy() {\n await Promise.all(this._peers.map((agent) => agent.destroy()));\n }\n\n /**\n * Simulates two peers connected via P2P network.\n */\n async createPipedPeers({ peerId1, peerId2 }: { peerId1?: PublicKey; peerId2?: PublicKey } = {}) {\n const peer1 = this.createPeer(peerId1);\n const peer2 = this.createPeer(peerId2);\n\n peer1.initializeTeleport({ initiator: true, remotePeerId: peer2.peerId });\n peer2.initializeTeleport({ initiator: false, remotePeerId: peer1.peerId });\n\n peer1.pipeline(peer2);\n peer2.pipeline(peer1);\n\n await Promise.all([peer1.teleport!.open(), peer2.teleport!.open()]);\n\n return { peer1, peer2 };\n }\n}\n\nexport class TestPeer {\n public teleport?: Teleport;\n\n constructor(public readonly peerId: PublicKey = PublicKey.random()) {}\n\n initializeTeleport({ initiator, remotePeerId }: { initiator: boolean; remotePeerId: PublicKey }) {\n if (this.teleport) {\n return this;\n }\n this.teleport = new Teleport({\n initiator,\n localPeerId: this.peerId,\n remotePeerId\n });\n return this;\n }\n\n pipeline(peer: TestPeer) {\n if (!this.teleport || !peer.teleport) {\n throw new Error('Teleport not initialized');\n }\n pipeline(this.teleport.stream, peer.teleport.stream, (err) => {\n if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {\n log.catch(err);\n }\n });\n }\n\n async destroy() {\n await this.teleport?.destroy();\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\nimport { Duplex } from 'node:stream';\n\nimport { asyncTimeout, scheduleTaskInterval, runInContextAsync, synchronized, scheduleTask } 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 } from '@dxos/protocols';\nimport { ControlService } from '@dxos/protocols/proto/dxos/mesh/teleport/control';\nimport { createProtoRpcPeer, ProtoRpcPeer, RpcClosedError } 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: 3000,\n heartbeatTimeout: 3000\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 assert(typeof initiator === 'boolean');\n assert(PublicKey.isPublicKey(localPeerId));\n assert(PublicKey.isPublicKey(remotePeerId));\n assert(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 assert(!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 /**\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 assert(!extensionName.includes('/'), 'Invalid extension name');\n assert(!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: (channelName: string, opts?: CreateChannelOpts) => {\n assert(!channelName.includes('/'), 'Invalid channel name');\n return this._muxer.createPort(`${extensionName}/${channelName}`, opts);\n },\n createStream: (channelName: string, opts?: CreateChannelOpts) => {\n assert(!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): Duplex;\n createPort(tag: string, opts?: CreateChannelOpts): 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};\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 public readonly onTimeout = new Callback<() => 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: extensionContext.createPort('rpc', {\n contentType: 'application/x-protobuf; messageType=\"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.onTimeout.call();\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 assert from 'node:assert';\nimport { Duplex } from 'node:stream';\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\n private readonly _stream = new Duplex({\n objectMode: false,\n read: () => {},\n write: (chunk, encoding, callback) => {\n assert(!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 this._stream.push(encodeFrame(message));\n },\n subscribe: (callback) => {\n assert(!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 /**\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.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 assert from 'node:assert';\nimport { Duplex } from 'node:stream';\n\nimport { Event } from '@dxos/async';\nimport { failUndefined } from '@dxos/debug';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { Command } from '@dxos/protocols/proto/dxos/mesh/muxer';\n\nimport { Framer } from './framer';\nimport { RpcPort } from './rpc-port';\n\nconst codec = 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\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 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 constructor() {\n this._framer.port.subscribe((msg) => {\n this._handleCommand(codec.decode(msg));\n });\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 createStream(tag: string, opts: CreateChannelOpts = {}): Duplex {\n const channel = this._getOrCreateStream({\n tag,\n contentType: opts.contentType\n });\n assert(!channel.push, `Channel already open: ${tag}`);\n\n const stream = new Duplex({\n write: (data, encoding, callback) => {\n this._sendData(channel, data);\n // TODO(dmaretskyi): Should we error if sending data has errored?\n callback();\n },\n read: () => {} // No-op. We will push data when we receive it.\n });\n\n channel.push = (data) => {\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 this._sendCommand({\n openChannel: {\n id: channel.id,\n tag: channel.tag,\n contentType: channel.contentType\n }\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 createPort(tag: string, opts: CreateChannelOpts = {}): RpcPort {\n const channel = this._getOrCreateStream({\n tag,\n contentType: opts.contentType\n });\n assert(!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 if (callback) {\n callback(data);\n } else {\n inboundBuffer.push(data);\n }\n };\n\n const port: RpcPort = {\n send: (data: Uint8Array) => {\n this._sendData(channel, data); // TODO(dmaretskyi): Error propagation?\n\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 assert(!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 this._sendCommand({\n openChannel: {\n id: channel.id,\n tag: channel.tag,\n contentType: channel.contentType\n }\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 this._sendCommand({\n destroy: {\n error: err?.message\n }\n });\n this._dispose();\n }\n\n private _dispose(err?: Error) {\n if (this._destroyed) {\n return;\n }\n\n this._destroyed = true;\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 _handleCommand(cmd: Command) {\n log('Received command', { cmd });\n\n if (this._destroyed || this._destroying) {\n log.warn('Received command after destroy');\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 this._sendCommand({\n data: {\n channelId: channel.remoteId,\n data\n }\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 _sendCommand(cmd: Command) {\n Promise.resolve(this._framer.port.send(codec.encode(cmd))).catch((err) => {\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 };\n this._channelsByTag.set(channel.tag, channel);\n this._channelsByLocalId.set(channel.id, channel);\n }\n return channel;\n }\n\n private _sendData(channel: Channel, data: Uint8Array) {\n if (channel.remoteId === null) {\n // Remote side has not opened the channel yet.\n channel.buffer.push(data);\n } else {\n this._sendCommand({\n data: {\n channelId: channel.remoteId,\n data\n }\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\ntype CreateChannelInternalParams = {\n tag: string;\n contentType?: string;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\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: 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: 1000\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() {\n await this.open.wait({ timeout: 500 });\n const res = await asyncTimeout(this._rpc.rpc.TestService.testCall({ data: 'test' }), 500);\n assert(res.data === 'test');\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;AAIA,SAASA,gBAAgB;AAEzB,SAASC,aAAAA,kBAAiB;AAC1B,SAASC,OAAAA,YAAW;;;ACHpB,OAAOC,aAAY;AAGnB,SAASC,cAAcC,sBAAsBC,mBAAmBC,cAAcC,oBAAoB;AAClG,SAASC,eAAe;AACxB,SAASC,iBAAAA,sBAAqB;AAC9B,SAASC,iBAAiB;AAC1B,SAASC,OAAAA,YAAW;AACpB,SAASC,UAAAA,eAAc;AAEvB,SAASC,oBAAkCC,sBAAsB;AACjE,SAASC,gBAAgB;;;ACXzB,OAAOC,YAAY;AACnB,SAASC,cAAc;AACvB,YAAYC,YAAY;AASjB,IAAMC,SAAN,MAAMA;EAAN;AAMYC,mBAAU,IAAIH,OAAO;MACpCI,YAAY;MACZC,MAAM,MAAM;MAAC;MACbC,OAAO,CAACC,OAAOC,UAAUC,aAAa;AACpCV,eAAO,CAAC,KAAKW,cAAc,kDAAA;AAE3B,YAAI,KAAKC,WAAW,KAAKA,QAAQC,SAAS,GAAG;AAC3C,eAAKD,UAAUE,OAAOC,OAAO;YAAC,KAAKH;YAASJ;WAAM;QACpD,OAAO;AACL,eAAKI,UAAUJ;QACjB;AAEA,YAAI,KAAKQ,YAAY;AACnB,eAAKC,WAAU;AACfP,mBAAAA;QACF,OAAO;AACL,eAAKC,eAAe,MAAM;AAExB,iBAAKM,WAAU;AACf,iBAAKN,eAAeO;AACpBR,qBAAAA;UACF;QACF;MACF;IACF,CAAA;AAEgBS,gBAAgB;MAC9BC,MAAM,CAACC,YAAY;AAEjB,aAAKjB,QAAQkB,KAAKC,YAAYF,OAAAA,CAAAA;MAChC;MACAG,WAAW,CAACd,aAAa;AApD7B;AAqDMV,eAAO,CAAC,KAAKgB,YAAY,0CAAA;AACzB,aAAKA,aAAaN;AAClB,mBAAKC,iBAAL;AACA,eAAO,MAAM;AACX,eAAKK,aAAaE;QACpB;MACF;IACF;;EAEA,IAAIO,SAAiB;AACnB,WAAO,KAAKrB;EACd;EAKQa,aAAa;AACnB,QAAIS,SAAS;AACb,WAAOA,SAAS,KAAKd,QAASC,QAAQ;AACpC,YAAMc,QAAQC,YAAY,KAAKhB,SAAUc,MAAAA;AAEzC,UAAI,CAACC,OAAO;AACV;MACF;AACAD,gBAAUC,MAAME;AAGhB,WAAKb,WAAYW,MAAMG,OAAO;IAChC;AAEA,QAAIJ,SAAS,KAAKd,QAASC,QAAQ;AAEjC,WAAKD,UAAU,KAAKA,QAASmB,SAASL,MAAAA;IACxC,OAAO;AACL,WAAKd,UAAUM;IACjB;EACF;EAEAc,UAAU;AAER,SAAK5B,QAAQ4B,QAAO;EACtB;AACF;AAKO,IAAMJ,cAAc,CAACK,QAAgBP,WAA2E;AACrH,MAAI;AACF,UAAMQ,cAAqBC,cAAOF,QAAQP,MAAAA;AAC1C,UAAMU,YAAmBD,cAAOE;AAEhC,QAAIJ,OAAOpB,SAASa,SAASU,YAAYF,aAAa;AAEpD,aAAOhB;IACT;AAEA,UAAMY,UAAUG,OAAOF,SAASL,SAASU,WAAWV,SAASU,YAAYF,WAAAA;AAEzE,WAAO;MACLJ;MACAD,eAAeO,YAAYF;IAC7B;EACF,SAASI,KAAP;AACA,QAAIA,eAAeC,YAAY;AAE7B,aAAOrB;IACT,OAAO;AACL,YAAMoB;IACR;EACF;AACF;AAEO,IAAMf,cAAc,CAACO,YAAgC;AAC1D,QAAMM,YAAmBI,sBAAeV,QAAQjB,MAAM;AACtD,QAAMc,QAAQb,OAAO2B,YAAYL,YAAYN,QAAQjB,MAAM;AAC3DX,EAAOwC,cAAOZ,QAAQjB,QAAQc,KAAAA;AAC9BA,QAAMgB,IAAIb,SAASM,SAAAA;AACnB,SAAOT;AACT;;;AChIA,OAAOiB,aAAY;AACnB,SAASC,UAAAA,eAAc;AAEvB,SAASC,aAAa;AACtB,SAASC,qBAAqB;AAC9B,SAASC,WAAW;AACpB,SAASC,cAAc;AAMvB,IAAMC,QAAQC,OAAOC,gBAAgB,yBAAA;AAyB9B,IAAMC,QAAN,MAAMA;EAaXC,cAAc;AAZGC,mBAAU,IAAIC,OAAAA;AACfC,kBAAS,KAAKF,QAAQE;AAErBC,8BAAqB,oBAAIC,IAAAA;AACzBC,0BAAiB,oBAAID,IAAAA;AAE9BE,mBAAU;AACVC,sBAAa;AACbC,uBAAc;AAEfC,iBAAQ,IAAIC,MAAAA;AAGjB,SAAKV,QAAQW,KAAKC,UAAU,CAACC,QAAQ;AACnC,WAAKC,eAAenB,MAAMoB,OAAOF,GAAAA,CAAAA;IACnC,CAAA;EACF;EAQAG,aAAaC,KAAaC,OAA0B,CAAC,GAAW;AAC9D,UAAMC,UAAU,KAAKC,mBAAmB;MACtCH;MACAI,aAAaH,KAAKG;IACpB,CAAA;AACAC,IAAAA,QAAO,CAACH,QAAQI,MAAM,yBAAyBN,KAAK;AAEpD,UAAMf,SAAS,IAAIsB,QAAO;MACxBC,OAAO,CAACC,MAAMC,UAAUC,aAAa;AACnC,aAAKC,UAAUV,SAASO,IAAAA;AAExBE,iBAAAA;MACF;MACAE,MAAM,MAAM;MAAC;IACf,CAAA;AAEAX,YAAQI,OAAO,CAACG,SAAS;AACvBxB,aAAOqB,KAAKG,IAAAA;IACd;AACAP,YAAQY,UAAU,CAACC,QAAQ;AAEzB9B,aAAO6B,QAAQC,GAAAA;IACjB;AAGA,SAAKC,aAAa;MAChBC,aAAa;QACXC,IAAIhB,QAAQgB;QACZlB,KAAKE,QAAQF;QACbI,aAAaF,QAAQE;MACvB;IACF,CAAA;AAEA,WAAOnB;EACT;EAQAkC,WAAWnB,KAAaC,OAA0B,CAAC,GAAY;AAC7D,UAAMC,UAAU,KAAKC,mBAAmB;MACtCH;MACAI,aAAaH,KAAKG;IACpB,CAAA;AACAC,IAAAA,QAAO,CAACH,QAAQI,MAAM,yBAAyBN,KAAK;AAGpD,QAAIoB,gBAA8B,CAAA;AAClC,QAAIT;AAEJT,YAAQI,OAAO,CAACG,SAAS;AACvB,UAAIE,UAAU;AACZA,iBAASF,IAAAA;MACX,OAAO;AACLW,sBAAcd,KAAKG,IAAAA;MACrB;IACF;AAEA,UAAMf,OAAgB;MACpB2B,MAAM,CAACZ,SAAqB;AAC1B,aAAKG,UAAUV,SAASO,IAAAA;MAI1B;MACAd,WAAW,CAAC2B,OAAmC;AAC7CjB,QAAAA,QAAO,CAACM,UAAU,gCAAA;AAClBA,mBAAWW;AACX,mBAAWb,QAAQW,eAAe;AAChCE,aAAGb,IAAAA;QACL;AACAW,wBAAgB,CAAA;MAClB;IACF;AAGA,SAAKJ,aAAa;MAChBC,aAAa;QACXC,IAAIhB,QAAQgB;QACZlB,KAAKE,QAAQF;QACbI,aAAaF,QAAQE;MACvB;IACF,CAAA;AAEA,WAAOV;EACT;EAKAoB,QAAQC,KAAa;AACnB,QAAI,KAAKxB,aAAa;AACpB;IACF;AACA,SAAKA,cAAc;AAEnB,SAAKyB,aAAa;MAChBF,SAAS;QACPS,OAAOR,2BAAKS;MACd;IACF,CAAA;AACA,SAAKC,SAAQ;EACf;EAEQA,SAASV,KAAa;AA7KhC;AA8KI,QAAI,KAAKzB,YAAY;AACnB;IACF;AAEA,SAAKA,aAAa;AAClB,SAAKP,QAAQ+B,QAAO;AAEpB,eAAWZ,WAAW,KAAKd,eAAesC,OAAM,GAAI;AAClDxB,oBAAQY,YAARZ,iCAAkBa;IACpB;AAEA,SAAKvB,MAAMmC,KAAKZ,GAAAA;AAGhB,SAAK7B,mBAAmB0C,MAAK;AAC7B,SAAKxC,eAAewC,MAAK;EAC3B;EAEQ/B,eAAegC,KAAc;AAhMvC;AAiMIC,QAAI,oBAAoB;MAAED;IAAI,GAAA;;;;;;AAE9B,QAAI,KAAKvC,cAAc,KAAKC,aAAa;AACvCuC,UAAIC,KAAK,kCAAA,CAAA,GAAA;;;;;;AACT;IACF;AAEA,QAAIF,IAAIZ,aAAa;AACnB,YAAMf,UAAU,KAAKC,mBAAmB;QACtCH,KAAK6B,IAAIZ,YAAYjB;QACrBI,aAAayB,IAAIZ,YAAYb;MAC/B,CAAA;AACAF,cAAQ8B,WAAWH,IAAIZ,YAAYC;AAGnC,iBAAWT,QAAQP,QAAQ+B,QAAQ;AACjC,aAAKjB,aAAa;UAChBP,MAAM;YACJyB,WAAWhC,QAAQ8B;YACnBvB;UACF;QACF,CAAA;MACF;AACAP,cAAQ+B,SAAS,CAAA;IACnB,WAAWJ,IAAIpB,MAAM;AACnB,YAAMxB,UAAS,UAAKC,mBAAmBiD,IAAIN,IAAIpB,KAAKyB,SAAS,MAA9C,YAAmDE,cAAAA;AAClE,UAAI,CAACnD,OAAOqB,MAAM;AAChBwB,YAAIC,KAAK,kDAAkD;UAAE/B,KAAKf,OAAOe;QAAI,GAAA;;;;;;AAC7E;MACF;AACAf,aAAOqB,KAAKuB,IAAIpB,KAAKA,IAAI;IAC3B,WAAWoB,IAAIf,SAAS;AACtB,WAAKW,SAAQ;IACf;EACF;EAEQT,aAAaa,KAAc;AACjCQ,YAAQC,QAAQ,KAAKvD,QAAQW,KAAK2B,KAAK3C,MAAM6D,OAAOV,GAAAA,CAAAA,CAAAA,EAAOW,MAAM,CAACzB,QAAQ;AACxE,WAAKD,QAAQC,GAAAA;IACf,CAAA;EACF;EAEQZ,mBAAmBsC,QAA8C;AACvE,QAAIvC,UAAU,KAAKd,eAAe+C,IAAIM,OAAOzC,GAAG;AAChD,QAAI,CAACE,SAAS;AACZA,gBAAU;QACRgB,IAAI,KAAK7B;QACT2C,UAAU;QACVhC,KAAKyC,OAAOzC;QACZI,aAAaqC,OAAOrC;QACpB6B,QAAQ,CAAA;QACR3B,MAAM;QACNQ,SAAS;MACX;AACA,WAAK1B,eAAesD,IAAIxC,QAAQF,KAAKE,OAAAA;AACrC,WAAKhB,mBAAmBwD,IAAIxC,QAAQgB,IAAIhB,OAAAA;IAC1C;AACA,WAAOA;EACT;EAEQU,UAAUV,SAAkBO,MAAkB;AACpD,QAAIP,QAAQ8B,aAAa,MAAM;AAE7B9B,cAAQ+B,OAAO3B,KAAKG,IAAAA;IACtB,OAAO;AACL,WAAKO,aAAa;QAChBP,MAAM;UACJyB,WAAWhC,QAAQ8B;UACnBvB;QACF;MACF,CAAA;IACF;EACF;AACF;;;AFtQA,IAAA,aAAA,SAAA,YAAA,QAAA,KAAA,MAAA;;;;;;;;;;AAqBO,IAAMkC,WAAN,MAAMA;EAyBXC,YAAY,EAAEC,WAAWC,aAAaC,aAAY,GAAoB;AApBrDC,gBAAO,IAAIC,QAAQ;MAClCC,SAAS,CAACC,QAAQ;AAChB,aAAK,KAAKC,QAAQD,GAAAA,EAAKE,MAAM,MAAM;AACjCC,UAAAA,KAAIC,MAAM,wBAAwBJ,KAAAA;;;;;;QACpC,CAAA;MACF;IACF,CAAA;AAEiBK,kBAAS,IAAIC,MAAAA;AAEbC,oBAAW,IAAIC,iBAAiB;MAC/CC,mBAAmB;MACnBC,kBAAkB;IACpB,CAAA;AAEiBC,uBAAc,oBAAIC,IAAAA;AAClBC,6BAAoB,oBAAIC,IAAAA;AAEjCC,iBAAQ;AAGdC,IAAAA,QAAO,OAAOtB,cAAc,SAAA;AAC5BsB,IAAAA,QAAOC,UAAUC,YAAYvB,WAAAA,CAAAA;AAC7BqB,IAAAA,QAAOC,UAAUC,YAAYtB,YAAAA,CAAAA;AAC7BoB,IAAAA,QAAO,OAAOtB,cAAc,SAAA;AAC5B,SAAKA,YAAYA;AACjB,SAAKC,cAAcA;AACnB,SAAKC,eAAeA;AAEpB,SAAKW,SAASY,sBAAsBC,IAAI,OAAOC,SAAS;AACtDlB,MAAAA,KAAI,oBAAoB;QAAEkB;MAAK,GAAA;;;;;;AAC/BL,MAAAA,QAAO,CAAC,KAAKH,kBAAkBS,IAAID,IAAAA,GAAO,iCAAA;AAC1C,WAAKR,kBAAkBU,IAAIF,IAAAA;AAE3B,UAAI,KAAKV,YAAYW,IAAID,IAAAA,GAAO;AAC9B,YAAI;AACF,gBAAM,KAAKG,eAAeH,IAAAA;QAC5B,SAASrB,KAAP;AACA,gBAAM,KAAKC,QAAQD,GAAAA;QACrB;MACF;IACF,CAAA;AAEA;AAEE,WAAKK,OAAOoB,OAAOC,GAAG,SAAS,YAAY;AACzC,cAAM,KAAKzB,QAAO;MACpB,CAAA;AAEA,WAAKI,OAAOoB,OAAOC,GAAG,SAAS,OAAO1B,QAAQ;AAC5C,cAAM,KAAKC,QAAQD,GAAAA;MACrB,CAAA;IACF;EACF;EAEA,IAAIyB,SAAiB;AACnB,WAAO,KAAKpB,OAAOoB;EACrB;EAKA,MAAME,OAAO;AACX,SAAKC,cAAc,8BAA8B,KAAKrB,QAAQ;AAC9D,UAAM,KAAKiB,eAAe,4BAAA;AAC1B,SAAKT,QAAQ;EACf;EAEA,MAAMc,MAAM7B,KAAa;AAGvB,UAAM,KAAKC,QAAQD,GAAAA;EACrB;EAEA,MACMC,QAAQD,KAAa;AACzB,QAAI,KAAKH,KAAKiC,UAAU;AACtB;IACF;AAEA,UAAM,KAAKjC,KAAKkC,QAAO;AAEvB,eAAWC,aAAa,KAAKrB,YAAYsB,OAAM,GAAI;AACjD,UAAI;AACF,cAAMD,UAAUE,QAAQlC,GAAAA;MAC1B,SAASA,MAAP;AACAG,QAAAA,KAAID,MAAMF,MAAAA,CAAAA,GAAAA;;;;;;MACZ;IACF;AAEA,SAAKK,OAAOJ,QAAQD,GAAAA;EACtB;EAEAmC,aAAad,MAAcW,WAA8B;AACvD,QAAI,CAAC,KAAKjB,OAAO;AACf,YAAM,IAAIqB,MAAM,UAAA;IAClB;AAEAjC,IAAAA,KAAI,gBAAgB;MAAEkB;IAAK,GAAA;;;;;;AAC3B,SAAKO,cAAcP,MAAMW,SAAAA;AAGzBK,iBAAa,KAAKxC,MAAM,YAAY;AAClC,UAAI;AACF,cAAM,KAAKU,SAAS+B,kBAAkBjB,IAAAA;MACxC,SAASrB,KAAP;AACA,YAAIA,eAAeuC,gBAAgB;AACjC;QACF;AACA,cAAMvC;MACR;IACF,CAAA;AAEA,QAAI,KAAKa,kBAAkBS,IAAID,IAAAA,GAAO;AAEpCgB,mBAAa,KAAKxC,MAAM,YAAY;AAClC,cAAM,KAAK2B,eAAeH,IAAAA;MAC5B,CAAA;IACF;EACF;EAEQO,cAAcY,eAAuBR,WAA8B;AACzEhB,IAAAA,QAAO,CAACwB,cAAcC,SAAS,GAAA,GAAM,wBAAA;AACrCzB,IAAAA,QAAO,CAAC,KAAKL,YAAYW,IAAIkB,aAAAA,GAAgB,0BAAA;AAC7C,SAAK7B,YAAYS,IAAIoB,eAAeR,SAAAA;EACtC;EAEA,MAAcR,eAAegB,eAAuB;AA7JtD;AA8JIrC,IAAAA,KAAI,kBAAkB;MAAEqC;IAAc,GAAA;;;;;;AACtC,UAAMR,aAAY,UAAKrB,YAAY+B,IAAIF,aAAAA,MAArB,YAAuCG,eAAAA;AAEzD,UAAMC,UAA4B;MAChClD,WAAW,KAAKA;MAChBC,aAAa,KAAKA;MAClBC,cAAc,KAAKA;MACnBiD,YAAY,CAACC,aAAqBC,SAA6B;AAC7D/B,QAAAA,QAAO,CAAC8B,YAAYL,SAAS,GAAA,GAAM,sBAAA;AACnC,eAAO,KAAKpC,OAAOwC,WAAW,GAAGL,iBAAiBM,eAAeC,IAAAA;MACnE;MACAC,cAAc,CAACF,aAAqBC,SAA6B;AAC/D/B,QAAAA,QAAO,CAAC8B,YAAYL,SAAS,GAAA,GAAM,sBAAA;AACnC,eAAO,KAAKpC,OAAO2C,aAAa,GAAGR,iBAAiBM,eAAeC,IAAAA;MACrE;MACAlB,OAAO,CAAC7B,QAAQ;AACd,aAAKiD,kBAAkB,KAAKpD,MAAM,YAAY;AAC5C,gBAAM,KAAKgC,MAAM7B,GAAAA;QACnB,CAAA;MACF;IACF;AAEA,UAAMgC,UAAUkB,OAAON,OAAAA;AACvBzC,IAAAA,KAAI,oBAAoB;MAAEqC;IAAc,GAAA;;;;;;EAC1C;AACF;;EA/EGW;GA/EU3D,SAAAA,WAAAA,WAAAA,IAAAA;AAsLb,IAAMgB,mBAAN,MAAMA;EAaJf,YAA6BsD,MAA4B;gBAA5BA;SAZZlD,OAAO,IAAIC,QAAQ;MAClCC,SAAS,CAACC,QAAQ;AAChB,aAAKoD,kBAAkBvB,MAAM7B,GAAAA;MAC/B;IACF,CAAA;SAKgBmB,wBAAwB,IAAIkC,SAAAA;SAC5BC,YAAY,IAAID,SAAAA;EAE0B;EAE1D,MAAMH,OAAOK,kBAAmD;AAC9D,SAAKH,oBAAoBG;AAIzB,SAAKC,OAAOC,mBAAuD;MACjEC,WAAW;QACTC,SAASC,QAAOC,WAAW,2CAAA;MAC7B;MACAC,SAAS;QACPH,SAASC,QAAOC,WAAW,2CAAA;MAC7B;MACAE,UAAU;QACRJ,SAAS;UACPrB,mBAAmB,OAAO0B,YAAY;AACpC,iBAAK7C,sBAAsB8C,KAAKD,QAAQ3C,IAAI;UAC9C;UACA6C,WAAW,OAAOF,YAAY;UAE9B;QACF;MACF;MACAG,MAAMZ,iBAAiBV,WAAW,OAAO;QACvCuB,aAAa;MACf,CAAA;IACF,CAAA;AAEA,UAAM,KAAKZ,KAAK7B,KAAI;AAEpB0C,yBACE,KAAKxE,MACL,YAAY;AACV,UAAI;AACF,cAAMyE,aAAa,KAAKd,KAAKe,IAAIZ,QAAQO,UAAS,GAAI,KAAKnB,KAAKrC,gBAAgB;MAClF,SAASV,KAAP;AACA,aAAKsD,UAAUW,KAAI;MACrB;IACF,GACA,KAAKlB,KAAKtC,iBAAiB;EAE/B;EAEA,MAAMyB,QAAQlC,KAA4B;AACxC,UAAM,KAAKH,KAAKkC,QAAO;AACvB,UAAM,KAAKyB,KAAK3B,MAAK;EACvB;EAEA,MAAMS,kBAAkBjB,MAAc;AACpC,UAAM,KAAKmC,KAAKe,IAAIZ,QAAQrB,kBAAkB;MAAEjB;IAAK,CAAA;EACvD;AACF;;;ADrQO,IAAMmD,cAAN,MAAMA;EAAN;AACYC,kBAAS,IAAIC,MAAAA;;EAE9BC,WAAWC,QAA8B;AACvC,UAAMC,OAAO,IAAIC,SAASF,MAAAA;AAC1B,SAAKH,OAAOM,KAAKF,IAAAA;AACjB,WAAOA;EACT;EAEA,MAAMG,UAAU;AACd,UAAMC,QAAQC,IAAI,KAAKT,OAAOU,IAAI,CAACC,UAAUA,MAAMJ,QAAO,CAAA,CAAA;EAC5D;EAKA,MAAMK,iBAAiB,EAAEC,SAASC,QAAO,IAAmD,CAAC,GAAG;AAC9F,UAAMC,QAAQ,KAAKb,WAAWW,OAAAA;AAC9B,UAAMG,QAAQ,KAAKd,WAAWY,OAAAA;AAE9BC,UAAME,mBAAmB;MAAEC,WAAW;MAAMC,cAAcH,MAAMb;IAAO,CAAA;AACvEa,UAAMC,mBAAmB;MAAEC,WAAW;MAAOC,cAAcJ,MAAMZ;IAAO,CAAA;AAExEY,UAAMK,SAASJ,KAAAA;AACfA,UAAMI,SAASL,KAAAA;AAEf,UAAMP,QAAQC,IAAI;MAACM,MAAMM,SAAUC,KAAI;MAAIN,MAAMK,SAAUC,KAAI;KAAG;AAElE,WAAO;MAAEP;MAAOC;IAAM;EACxB;AACF;AAEO,IAAMX,WAAN,MAAMA;EAGXkB,YAA4BpB,SAAoBqB,WAAUC,OAAM,GAAI;kBAAxCtB;EAAyC;EAErEc,mBAAmB,EAAEC,WAAWC,aAAY,GAAqD;AAC/F,QAAI,KAAKE,UAAU;AACjB,aAAO;IACT;AACA,SAAKA,WAAW,IAAIK,SAAS;MAC3BR;MACAS,aAAa,KAAKxB;MAClBgB;IACF,CAAA;AACA,WAAO;EACT;EAEAC,SAAShB,MAAgB;AACvB,QAAI,CAAC,KAAKiB,YAAY,CAACjB,KAAKiB,UAAU;AACpC,YAAM,IAAIO,MAAM,0BAAA;IAClB;AACAR,aAAS,KAAKC,SAASQ,QAAQzB,KAAKiB,SAASQ,QAAQ,CAACC,QAAQ;AAC5D,UAAIA,OAAOA,IAAIC,SAAS,8BAA8B;AACpDC,QAAAA,KAAIC,MAAMH,KAAAA,CAAAA,GAAAA;;;;;;MACZ;IACF,CAAA;EACF;EAEA,MAAMvB,UAAU;AAvElB;AAwEI,YAAM,UAAKc,aAAL,mBAAed;EACvB;AACF;;;AItEA,OAAO2B,aAAY;AAEnB,SAASC,gBAAAA,eAAcC,eAAe;AACtC,SAASC,OAAAA,YAAW;AACpB,SAASC,UAAAA,eAAc;AAEvB,SAASC,sBAAAA,2BAAwC;AAS1C,IAAMC,gBAAN,MAAMA;EAMXC,YAA4BC,YAAoC,CAAC,GAAG;qBAAxCA;SALZC,OAAO,IAAIP,QAAAA;SACXQ,SAAS,IAAIR,QAAAA;EAIwC;EAErE,IAAIS,eAAe;AA3BrB;AA4BI,YAAO,UAAKC,qBAAL,mBAAuBD;EAChC;EAEA,MAAME,OAAOC,SAA2B;AA/B1C;AAgCIX,IAAAA,KAAI,UAAU;MAAEY,aAAaD,QAAQC;MAAaJ,cAAcG,QAAQH;IAAa,GAAA;;;;;;AACrF,SAAKC,mBAAmBE;AACxB,SAAKE,OAAOX,oBAA+E;MACzFY,MAAMH,QAAQI,WAAW,OAAO;QAC9BC,aAAa;MACf,CAAA;MACAC,WAAW;QACTC,aAAajB,QAAOkB,WAAW,iCAAA;MACjC;MACAC,SAAS;QACPF,aAAajB,QAAOkB,WAAW,iCAAA;MACjC;MACAE,UAAU;QACRH,aAAa;UACXI,UAAU,OAAOC,YAAY;UAE7B;UACAC,UAAU,OAAOD,YAAY;AAC3B,mBAAO;cACLE,MAAMF,QAAQE;YAChB;UACF;QACF;MACF;MACAC,SAAS;IACX,CAAA;AAEA,UAAM,KAAKb,KAAKP,KAAI;AACpB,YAAM,gBAAKD,WAAUK,WAAf;AAEN,SAAKJ,KAAKqB,KAAI;EAChB;EAEA,MAAMC,QAAQC,KAAa;AAjE7B;AAkEI7B,IAAAA,KAAI,WAAW;MAAE6B;IAAI,GAAA;;;;;;AACrB,YAAM,gBAAKxB,WAAUuB,YAAf;AACN,SAAKrB,OAAOoB,KAAI;AAChB,YAAM,UAAKd,SAAL,mBAAWiB;EACnB;EAEA,MAAMC,OAAO;AACX,UAAM,KAAKzB,KAAK0B,KAAK;MAAEN,SAAS;IAAI,CAAA;AACpC,UAAMO,MAAM,MAAMnC,cAAa,KAAKe,KAAKqB,IAAIhB,YAAYM,SAAS;MAAEC,MAAM;IAAO,CAAA,GAAI,GAAA;AACrF5B,IAAAA,QAAOoC,IAAIR,SAAS,MAAA;EACtB;AACF;",
|
|
6
|
+
"names": ["pipeline", "PublicKey", "log", "assert", "asyncTimeout", "scheduleTaskInterval", "runInContextAsync", "synchronized", "scheduleTask", "Context", "failUndefined", "PublicKey", "log", "schema", "createProtoRpcPeer", "RpcClosedError", "Callback", "assert", "Duplex", "varint", "Framer", "_stream", "objectMode", "read", "write", "chunk", "encoding", "callback", "_subscribeCb", "_buffer", "length", "Buffer", "concat", "_messageCb", "_popFrames", "undefined", "port", "send", "message", "push", "encodeFrame", "subscribe", "stream", "offset", "frame", "decodeFrame", "bytesConsumed", "payload", "subarray", "destroy", "buffer", "frameLength", "decode", "tagLength", "bytes", "err", "RangeError", "encodingLength", "allocUnsafe", "encode", "set", "assert", "Duplex", "Event", "failUndefined", "log", "schema", "codec", "schema", "getCodecForType", "Muxer", "constructor", "_framer", "Framer", "stream", "_channelsByLocalId", "Map", "_channelsByTag", "_nextId", "_destroyed", "_destroying", "close", "Event", "port", "subscribe", "msg", "_handleCommand", "decode", "createStream", "tag", "opts", "channel", "_getOrCreateStream", "contentType", "assert", "push", "Duplex", "write", "data", "encoding", "callback", "_sendData", "read", "destroy", "err", "_sendCommand", "openChannel", "id", "createPort", "inboundBuffer", "send", "cb", "error", "message", "_dispose", "values", "emit", "clear", "cmd", "log", "warn", "remoteId", "buffer", "channelId", "get", "failUndefined", "Promise", "resolve", "encode", "catch", "params", "set", "Teleport", "constructor", "initiator", "localPeerId", "remotePeerId", "_ctx", "Context", "onError", "err", "destroy", "catch", "log", "error", "_muxer", "Muxer", "_control", "ControlExtension", "heartbeatInterval", "heartbeatTimeout", "_extensions", "Map", "_remoteExtensions", "Set", "_open", "assert", "PublicKey", "isPublicKey", "onExtensionRegistered", "set", "name", "has", "add", "_openExtension", "stream", "on", "open", "_setExtension", "close", "disposed", "dispose", "extension", "values", "onClose", "addExtension", "Error", "scheduleTask", "registerExtension", "RpcClosedError", "extensionName", "includes", "get", "failUndefined", "context", "createPort", "channelName", "opts", "createStream", "runInContextAsync", "onOpen", "synchronized", "_extensionContext", "Callback", "onTimeout", "extensionContext", "_rpc", "createProtoRpcPeer", "requested", "Control", "schema", "getService", "exposed", "handlers", "request", "call", "heartbeat", "port", "contentType", "scheduleTaskInterval", "asyncTimeout", "rpc", "TestBuilder", "_peers", "Array", "createPeer", "peerId", "peer", "TestPeer", "push", "destroy", "Promise", "all", "map", "agent", "createPipedPeers", "peerId1", "peerId2", "peer1", "peer2", "initializeTeleport", "initiator", "remotePeerId", "pipeline", "teleport", "open", "constructor", "PublicKey", "random", "Teleport", "localPeerId", "Error", "stream", "err", "code", "log", "catch", "assert", "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", "wait", "res", "rpc"]
|
|
7
|
+
}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -28,8 +28,11 @@ var src_exports = {};
|
|
|
28
28
|
__export(src_exports, {
|
|
29
29
|
Framer: () => Framer,
|
|
30
30
|
Muxer: () => Muxer,
|
|
31
|
+
RpcExtension: () => RpcExtension,
|
|
31
32
|
Teleport: () => Teleport,
|
|
32
|
-
|
|
33
|
+
TestExtension: () => TestExtension,
|
|
34
|
+
decodeFrame: () => decodeFrame,
|
|
35
|
+
encodeFrame: () => encodeFrame
|
|
33
36
|
});
|
|
34
37
|
module.exports = __toCommonJS(src_exports);
|
|
35
38
|
|
|
@@ -67,8 +70,7 @@ var Framer = class {
|
|
|
67
70
|
});
|
|
68
71
|
this.port = {
|
|
69
72
|
send: (message) => {
|
|
70
|
-
this._stream.push(
|
|
71
|
-
this._stream.push(message);
|
|
73
|
+
this._stream.push(encodeFrame(message));
|
|
72
74
|
},
|
|
73
75
|
subscribe: (callback) => {
|
|
74
76
|
var _a;
|
|
@@ -87,7 +89,7 @@ var Framer = class {
|
|
|
87
89
|
_popFrames() {
|
|
88
90
|
let offset = 0;
|
|
89
91
|
while (offset < this._buffer.length) {
|
|
90
|
-
const frame =
|
|
92
|
+
const frame = decodeFrame(this._buffer, offset);
|
|
91
93
|
if (!frame) {
|
|
92
94
|
break;
|
|
93
95
|
}
|
|
@@ -104,7 +106,7 @@ var Framer = class {
|
|
|
104
106
|
this._stream.destroy();
|
|
105
107
|
}
|
|
106
108
|
};
|
|
107
|
-
var
|
|
109
|
+
var decodeFrame = (buffer, offset) => {
|
|
108
110
|
try {
|
|
109
111
|
const frameLength = varint.decode(buffer, offset);
|
|
110
112
|
const tagLength = varint.decode.bytes;
|
|
@@ -124,12 +126,12 @@ var readFrame = (buffer, offset) => {
|
|
|
124
126
|
}
|
|
125
127
|
}
|
|
126
128
|
};
|
|
127
|
-
var
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return
|
|
129
|
+
var encodeFrame = (payload) => {
|
|
130
|
+
const tagLength = varint.encodingLength(payload.length);
|
|
131
|
+
const frame = Buffer.allocUnsafe(tagLength + payload.length);
|
|
132
|
+
varint.encode(payload.length, frame);
|
|
133
|
+
frame.set(payload, tagLength);
|
|
134
|
+
return frame;
|
|
133
135
|
};
|
|
134
136
|
|
|
135
137
|
// packages/core/mesh/teleport/src/muxing/muxer.ts
|
|
@@ -251,14 +253,14 @@ var Muxer = class {
|
|
|
251
253
|
(0, import_log.log)("Received command", {
|
|
252
254
|
cmd
|
|
253
255
|
}, {
|
|
254
|
-
file: "
|
|
256
|
+
file: "muxer.ts",
|
|
255
257
|
line: 194,
|
|
256
258
|
scope: this,
|
|
257
259
|
callSite: (f, a) => f(...a)
|
|
258
260
|
});
|
|
259
261
|
if (this._destroyed || this._destroying) {
|
|
260
262
|
import_log.log.warn("Received command after destroy", {}, {
|
|
261
|
-
file: "
|
|
263
|
+
file: "muxer.ts",
|
|
262
264
|
line: 197,
|
|
263
265
|
scope: this,
|
|
264
266
|
callSite: (f, a) => f(...a)
|
|
@@ -286,7 +288,7 @@ var Muxer = class {
|
|
|
286
288
|
import_log.log.warn("Received data for channel before it was opened", {
|
|
287
289
|
tag: stream.tag
|
|
288
290
|
}, {
|
|
289
|
-
file: "
|
|
291
|
+
file: "muxer.ts",
|
|
290
292
|
line: 221,
|
|
291
293
|
scope: this,
|
|
292
294
|
callSite: (f, a) => f(...a)
|
|
@@ -360,7 +362,7 @@ var Teleport = class {
|
|
|
360
362
|
onError: (err) => {
|
|
361
363
|
void this.destroy(err).catch(() => {
|
|
362
364
|
import_log2.log.error("Error during destroy", err, {
|
|
363
|
-
file: "
|
|
365
|
+
file: "teleport.ts",
|
|
364
366
|
line: 34,
|
|
365
367
|
scope: this,
|
|
366
368
|
callSite: (f, a) => f(...a)
|
|
@@ -387,7 +389,7 @@ var Teleport = class {
|
|
|
387
389
|
(0, import_log2.log)("remote extension", {
|
|
388
390
|
name
|
|
389
391
|
}, {
|
|
390
|
-
file: "
|
|
392
|
+
file: "teleport.ts",
|
|
391
393
|
line: 61,
|
|
392
394
|
scope: this,
|
|
393
395
|
callSite: (f, a) => f(...a)
|
|
@@ -432,7 +434,7 @@ var Teleport = class {
|
|
|
432
434
|
await extension.onClose(err);
|
|
433
435
|
} catch (err1) {
|
|
434
436
|
import_log2.log.catch(err1, {}, {
|
|
435
|
-
file: "
|
|
437
|
+
file: "teleport.ts",
|
|
436
438
|
line: 117,
|
|
437
439
|
scope: this,
|
|
438
440
|
callSite: (f, a) => f(...a)
|
|
@@ -448,7 +450,7 @@ var Teleport = class {
|
|
|
448
450
|
(0, import_log2.log)("addExtension", {
|
|
449
451
|
name
|
|
450
452
|
}, {
|
|
451
|
-
file: "
|
|
453
|
+
file: "teleport.ts",
|
|
452
454
|
line: 129,
|
|
453
455
|
scope: this,
|
|
454
456
|
callSite: (f, a) => f(...a)
|
|
@@ -480,7 +482,7 @@ var Teleport = class {
|
|
|
480
482
|
(0, import_log2.log)("open extension", {
|
|
481
483
|
extensionName
|
|
482
484
|
}, {
|
|
483
|
-
file: "
|
|
485
|
+
file: "teleport.ts",
|
|
484
486
|
line: 159,
|
|
485
487
|
scope: this,
|
|
486
488
|
callSite: (f, a) => f(...a)
|
|
@@ -508,7 +510,7 @@ var Teleport = class {
|
|
|
508
510
|
(0, import_log2.log)("extension opened", {
|
|
509
511
|
extensionName
|
|
510
512
|
}, {
|
|
511
|
-
file: "
|
|
513
|
+
file: "teleport.ts",
|
|
512
514
|
line: 182,
|
|
513
515
|
scope: this,
|
|
514
516
|
callSite: (f, a) => f(...a)
|
|
@@ -570,11 +572,153 @@ var ControlExtension = class {
|
|
|
570
572
|
});
|
|
571
573
|
}
|
|
572
574
|
};
|
|
575
|
+
|
|
576
|
+
// packages/core/mesh/teleport/src/testing/test-extension.ts
|
|
577
|
+
var import_node_assert4 = __toESM(require("node:assert"));
|
|
578
|
+
var import_async3 = require("@dxos/async");
|
|
579
|
+
var import_log3 = require("@dxos/log");
|
|
580
|
+
var import_protocols3 = require("@dxos/protocols");
|
|
581
|
+
var import_rpc2 = require("@dxos/rpc");
|
|
582
|
+
var TestExtension = class {
|
|
583
|
+
constructor(callbacks = {}) {
|
|
584
|
+
this.callbacks = callbacks;
|
|
585
|
+
this.open = new import_async3.Trigger();
|
|
586
|
+
this.closed = new import_async3.Trigger();
|
|
587
|
+
}
|
|
588
|
+
get remotePeerId() {
|
|
589
|
+
var _a;
|
|
590
|
+
return (_a = this.extensionContext) == null ? void 0 : _a.remotePeerId;
|
|
591
|
+
}
|
|
592
|
+
async onOpen(context) {
|
|
593
|
+
var _a, _b;
|
|
594
|
+
(0, import_log3.log)("onOpen", {
|
|
595
|
+
localPeerId: context.localPeerId,
|
|
596
|
+
remotePeerId: context.remotePeerId
|
|
597
|
+
}, {
|
|
598
|
+
file: "test-extension.ts",
|
|
599
|
+
line: 33,
|
|
600
|
+
scope: this,
|
|
601
|
+
callSite: (f, a) => f(...a)
|
|
602
|
+
});
|
|
603
|
+
this.extensionContext = context;
|
|
604
|
+
this._rpc = (0, import_rpc2.createProtoRpcPeer)({
|
|
605
|
+
port: context.createPort("rpc", {
|
|
606
|
+
contentType: 'application/x-protobuf; messageType="dxos.rpc.Message"'
|
|
607
|
+
}),
|
|
608
|
+
requested: {
|
|
609
|
+
TestService: import_protocols3.schema.getService("example.testing.rpc.TestService")
|
|
610
|
+
},
|
|
611
|
+
exposed: {
|
|
612
|
+
TestService: import_protocols3.schema.getService("example.testing.rpc.TestService")
|
|
613
|
+
},
|
|
614
|
+
handlers: {
|
|
615
|
+
TestService: {
|
|
616
|
+
voidCall: async (request) => {
|
|
617
|
+
},
|
|
618
|
+
testCall: async (request) => {
|
|
619
|
+
return {
|
|
620
|
+
data: request.data
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
},
|
|
625
|
+
timeout: 1e3
|
|
626
|
+
});
|
|
627
|
+
await this._rpc.open();
|
|
628
|
+
await ((_b = (_a = this.callbacks).onOpen) == null ? void 0 : _b.call(_a));
|
|
629
|
+
this.open.wake();
|
|
630
|
+
}
|
|
631
|
+
async onClose(err) {
|
|
632
|
+
var _a, _b, _c;
|
|
633
|
+
(0, import_log3.log)("onClose", {
|
|
634
|
+
err
|
|
635
|
+
}, {
|
|
636
|
+
file: "test-extension.ts",
|
|
637
|
+
line: 67,
|
|
638
|
+
scope: this,
|
|
639
|
+
callSite: (f, a) => f(...a)
|
|
640
|
+
});
|
|
641
|
+
await ((_b = (_a = this.callbacks).onClose) == null ? void 0 : _b.call(_a));
|
|
642
|
+
this.closed.wake();
|
|
643
|
+
await ((_c = this._rpc) == null ? void 0 : _c.close());
|
|
644
|
+
}
|
|
645
|
+
async test() {
|
|
646
|
+
await this.open.wait({
|
|
647
|
+
timeout: 500
|
|
648
|
+
});
|
|
649
|
+
const res = await (0, import_async3.asyncTimeout)(this._rpc.rpc.TestService.testCall({
|
|
650
|
+
data: "test"
|
|
651
|
+
}), 500);
|
|
652
|
+
(0, import_node_assert4.default)(res.data === "test");
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
// packages/core/mesh/teleport/src/rpc-extension.ts
|
|
657
|
+
var import_node_assert5 = __toESM(require("node:assert"));
|
|
658
|
+
var import_async4 = require("@dxos/async");
|
|
659
|
+
var import_rpc3 = require("@dxos/rpc");
|
|
660
|
+
var __decorate2 = function(decorators, target, key, desc) {
|
|
661
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
662
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
663
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
664
|
+
else
|
|
665
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
666
|
+
if (d = decorators[i])
|
|
667
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
668
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
669
|
+
};
|
|
670
|
+
var RpcExtension = class {
|
|
671
|
+
constructor(_params) {
|
|
672
|
+
this._params = _params;
|
|
673
|
+
}
|
|
674
|
+
get initiator() {
|
|
675
|
+
return this._extensionContext.initiator;
|
|
676
|
+
}
|
|
677
|
+
get localPeerId() {
|
|
678
|
+
return this._extensionContext.localPeerId;
|
|
679
|
+
}
|
|
680
|
+
get remotePeerId() {
|
|
681
|
+
return this._extensionContext.remotePeerId;
|
|
682
|
+
}
|
|
683
|
+
get rpc() {
|
|
684
|
+
(0, import_node_assert5.default)(this._rpc);
|
|
685
|
+
return this._rpc.rpc;
|
|
686
|
+
}
|
|
687
|
+
async onOpen(context) {
|
|
688
|
+
this._extensionContext = context;
|
|
689
|
+
const handlers = await this.getHandlers();
|
|
690
|
+
const port = context.createPort("rpc", {
|
|
691
|
+
contentType: 'application/x-protobuf; messageType="dxos.rpc.Message"'
|
|
692
|
+
});
|
|
693
|
+
this._rpc = (0, import_rpc3.createProtoRpcPeer)({
|
|
694
|
+
...this._params,
|
|
695
|
+
handlers,
|
|
696
|
+
port
|
|
697
|
+
});
|
|
698
|
+
await this._rpc.open();
|
|
699
|
+
}
|
|
700
|
+
async onClose(err) {
|
|
701
|
+
var _a;
|
|
702
|
+
await ((_a = this._rpc) == null ? void 0 : _a.close());
|
|
703
|
+
}
|
|
704
|
+
close() {
|
|
705
|
+
this._extensionContext.close();
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
__decorate2([
|
|
709
|
+
import_async4.synchronized
|
|
710
|
+
], RpcExtension.prototype, "onOpen", null);
|
|
711
|
+
__decorate2([
|
|
712
|
+
import_async4.synchronized
|
|
713
|
+
], RpcExtension.prototype, "onClose", null);
|
|
573
714
|
// Annotate the CommonJS export names for ESM import in node:
|
|
574
715
|
0 && (module.exports = {
|
|
575
716
|
Framer,
|
|
576
717
|
Muxer,
|
|
718
|
+
RpcExtension,
|
|
577
719
|
Teleport,
|
|
578
|
-
|
|
720
|
+
TestExtension,
|
|
721
|
+
decodeFrame,
|
|
722
|
+
encodeFrame
|
|
579
723
|
});
|
|
580
724
|
//# sourceMappingURL=index.cjs.map
|