@dxos/teleport 0.1.31-next.ea8f0bc → 0.1.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/{chunk-F3DXMBSX.mjs → chunk-JWCTCCDW.mjs} +11 -4
- package/dist/lib/browser/{chunk-F3DXMBSX.mjs.map → chunk-JWCTCCDW.mjs.map} +3 -3
- package/dist/lib/browser/index.mjs +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +1 -1
- package/dist/lib/node/index.cjs +10 -3
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +10 -3
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/types/src/testing/test-extension.d.ts +5 -1
- package/dist/types/src/testing/test-extension.d.ts.map +1 -1
- package/package.json +10 -10
- package/src/testing/test-extension.ts +10 -3
|
@@ -635,14 +635,21 @@ var TestExtension = class {
|
|
|
635
635
|
this.closed.wake();
|
|
636
636
|
await ((_c = this._rpc) == null ? void 0 : _c.close());
|
|
637
637
|
}
|
|
638
|
-
async test() {
|
|
638
|
+
async test(message = "test") {
|
|
639
639
|
await this.open.wait({
|
|
640
640
|
timeout: 500
|
|
641
641
|
});
|
|
642
642
|
const res = await asyncTimeout2(this._rpc.rpc.TestService.testCall({
|
|
643
|
-
data:
|
|
643
|
+
data: message
|
|
644
644
|
}), 500);
|
|
645
|
-
assert4(res.data ===
|
|
645
|
+
assert4(res.data === message);
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Force-close the connection.
|
|
649
|
+
*/
|
|
650
|
+
async closeConnection(err) {
|
|
651
|
+
var _a;
|
|
652
|
+
(_a = this.extensionContext) == null ? void 0 : _a.close(err);
|
|
646
653
|
}
|
|
647
654
|
};
|
|
648
655
|
|
|
@@ -654,4 +661,4 @@ export {
|
|
|
654
661
|
Teleport,
|
|
655
662
|
TestExtension
|
|
656
663
|
};
|
|
657
|
-
//# sourceMappingURL=chunk-
|
|
664
|
+
//# sourceMappingURL=chunk-JWCTCCDW.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/muxing/framer.ts", "../../../src/muxing/muxer.ts", "../../../src/teleport.ts", "../../../src/testing/test-extension.ts"],
|
|
4
|
-
"sourcesContent": ["//\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';\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 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 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 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: 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 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": "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",
|
|
6
|
-
"names": ["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", "assert", "asyncTimeout", "scheduleTaskInterval", "runInContextAsync", "synchronized", "scheduleTask", "Context", "failUndefined", "PublicKey", "log", "schema", "createProtoRpcPeer", "RpcClosedError", "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", "assert", "PublicKey", "isPublicKey", "onExtensionRegistered", "set", "name", "has", "add", "_openExtension", "stream", "on", "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", "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"]
|
|
4
|
+
"sourcesContent": ["//\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';\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 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 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 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: 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 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(message = 'test') {\n await this.open.wait({ timeout: 500 });\n const res = await asyncTimeout(this._rpc.rpc.TestService.testCall({ data: message }), 500);\n assert(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": ["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", "assert", "asyncTimeout", "scheduleTaskInterval", "runInContextAsync", "synchronized", "scheduleTask", "Context", "failUndefined", "PublicKey", "log", "schema", "createProtoRpcPeer", "RpcClosedError", "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", "assert", "PublicKey", "isPublicKey", "onExtensionRegistered", "set", "name", "has", "add", "_openExtension", "stream", "on", "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", "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", "message", "wait", "res", "rpc", "closeConnection"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/core/mesh/teleport/src/muxing/framer.ts":{"bytes":12785,"imports":[{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/node-std/stream","kind":"import-statement","external":true},{"path":"varint","kind":"import-statement","external":true}]},"packages/core/mesh/teleport/src/muxing/muxer.ts":{"bytes":25338,"imports":[{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/node-std/stream","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport/src/muxing/framer.ts","kind":"import-statement","original":"./framer"}]},"packages/core/mesh/teleport/src/muxing/rpc-port.ts":{"bytes":824,"imports":[]},"packages/core/mesh/teleport/src/muxing/index.ts":{"bytes":539,"imports":[{"path":"packages/core/mesh/teleport/src/muxing/framer.ts","kind":"import-statement","original":"./framer"},{"path":"packages/core/mesh/teleport/src/muxing/muxer.ts","kind":"import-statement","original":"./muxer"},{"path":"packages/core/mesh/teleport/src/muxing/rpc-port.ts","kind":"import-statement","original":"./rpc-port"}]},"packages/core/mesh/teleport/src/teleport.ts":{"bytes":27932,"imports":[{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport/src/muxing/index.ts","kind":"import-statement","original":"./muxing"}]},"packages/core/mesh/teleport/src/testing/test-extension.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/core/mesh/teleport/src/muxing/framer.ts":{"bytes":12785,"imports":[{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/node-std/stream","kind":"import-statement","external":true},{"path":"varint","kind":"import-statement","external":true}]},"packages/core/mesh/teleport/src/muxing/muxer.ts":{"bytes":25338,"imports":[{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/node-std/stream","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport/src/muxing/framer.ts","kind":"import-statement","original":"./framer"}]},"packages/core/mesh/teleport/src/muxing/rpc-port.ts":{"bytes":824,"imports":[]},"packages/core/mesh/teleport/src/muxing/index.ts":{"bytes":539,"imports":[{"path":"packages/core/mesh/teleport/src/muxing/framer.ts","kind":"import-statement","original":"./framer"},{"path":"packages/core/mesh/teleport/src/muxing/muxer.ts","kind":"import-statement","original":"./muxer"},{"path":"packages/core/mesh/teleport/src/muxing/rpc-port.ts","kind":"import-statement","original":"./rpc-port"}]},"packages/core/mesh/teleport/src/teleport.ts":{"bytes":27932,"imports":[{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport/src/muxing/index.ts","kind":"import-statement","original":"./muxing"}]},"packages/core/mesh/teleport/src/testing/test-extension.ts":{"bytes":8458,"imports":[{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}]},"packages/core/mesh/teleport/src/rpc-extension.ts":{"bytes":5055,"imports":[{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}]},"packages/core/mesh/teleport/src/index.ts":{"bytes":685,"imports":[{"path":"packages/core/mesh/teleport/src/muxing/index.ts","kind":"import-statement","original":"./muxing"},{"path":"packages/core/mesh/teleport/src/teleport.ts","kind":"import-statement","original":"./teleport"},{"path":"packages/core/mesh/teleport/src/testing/test-extension.ts","kind":"import-statement","original":"./testing/test-extension"},{"path":"packages/core/mesh/teleport/src/rpc-extension.ts","kind":"import-statement","original":"./rpc-extension"}]},"packages/core/mesh/teleport/src/testing/test-builder.ts":{"bytes":13440,"imports":[{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/node-std/stream","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport/src/teleport.ts","kind":"import-statement","original":"../teleport"}]},"packages/core/mesh/teleport/src/testing/index.ts":{"bytes":494,"imports":[{"path":"packages/core/mesh/teleport/src/testing/test-builder.ts","kind":"import-statement","original":"./test-builder"},{"path":"packages/core/mesh/teleport/src/testing/test-extension.ts","kind":"import-statement","original":"./test-extension"}]}},"outputs":{"packages/core/mesh/teleport/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":2705},"packages/core/mesh/teleport/dist/lib/browser/index.mjs":{"imports":[{"path":"packages/core/mesh/teleport/dist/lib/browser/chunk-JWCTCCDW.mjs","kind":"import-statement"},{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}],"exports":["Framer","Muxer","RpcExtension","Teleport","TestExtension","decodeFrame","encodeFrame"],"entryPoint":"packages/core/mesh/teleport/src/index.ts","inputs":{"packages/core/mesh/teleport/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport/src/rpc-extension.ts":{"bytesInOutput":1094}},"bytes":1436},"packages/core/mesh/teleport/dist/lib/browser/testing/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":6996},"packages/core/mesh/teleport/dist/lib/browser/testing/index.mjs":{"imports":[{"path":"packages/core/mesh/teleport/dist/lib/browser/chunk-JWCTCCDW.mjs","kind":"import-statement"},{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/node-std/stream","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"exports":["TestBuilder","TestConnection","TestExtension","TestPeer"],"entryPoint":"packages/core/mesh/teleport/src/testing/index.ts","inputs":{"packages/core/mesh/teleport/src/testing/test-builder.ts":{"bytesInOutput":3472},"packages/core/mesh/teleport/src/testing/index.ts":{"bytesInOutput":0}},"bytes":3741},"packages/core/mesh/teleport/dist/lib/browser/chunk-JWCTCCDW.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":36690},"packages/core/mesh/teleport/dist/lib/browser/chunk-JWCTCCDW.mjs":{"imports":[{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/node-std/stream","kind":"import-statement","external":true},{"path":"varint","kind":"import-statement","external":true},{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/node-std/stream","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/node-std/assert","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}],"exports":["Framer","Muxer","Teleport","TestExtension","decodeFrame","encodeFrame"],"inputs":{"packages/core/mesh/teleport/src/muxing/framer.ts":{"bytesInOutput":2645},"packages/core/mesh/teleport/src/muxing/muxer.ts":{"bytesInOutput":5748},"packages/core/mesh/teleport/src/muxing/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport/src/teleport.ts":{"bytesInOutput":7413},"packages/core/mesh/teleport/src/testing/test-extension.ts":{"bytesInOutput":2378}},"bytes":18565}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -675,14 +675,21 @@ var TestExtension = class {
|
|
|
675
675
|
this.closed.wake();
|
|
676
676
|
await ((_c = this._rpc) == null ? void 0 : _c.close());
|
|
677
677
|
}
|
|
678
|
-
async test() {
|
|
678
|
+
async test(message = "test") {
|
|
679
679
|
await this.open.wait({
|
|
680
680
|
timeout: 500
|
|
681
681
|
});
|
|
682
682
|
const res = await (0, import_async3.asyncTimeout)(this._rpc.rpc.TestService.testCall({
|
|
683
|
-
data:
|
|
683
|
+
data: message
|
|
684
684
|
}), 500);
|
|
685
|
-
(0, import_node_assert4.default)(res.data ===
|
|
685
|
+
(0, import_node_assert4.default)(res.data === message);
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Force-close the connection.
|
|
689
|
+
*/
|
|
690
|
+
async closeConnection(err) {
|
|
691
|
+
var _a;
|
|
692
|
+
(_a = this.extensionContext) == null ? void 0 : _a.close(err);
|
|
686
693
|
}
|
|
687
694
|
};
|
|
688
695
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/index.ts", "../../../src/muxing/framer.ts", "../../../src/muxing/muxer.ts", "../../../src/teleport.ts", "../../../src/testing/test-extension.ts", "../../../src/rpc-extension.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nexport * from './muxing';\nexport * from './teleport';\nexport * from './testing/test-extension';\nexport * from './rpc-extension';\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';\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 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 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 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: 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 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", "//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\n\nimport { createProtoRpcPeer, ProtoRpcPeer, ProtoRpcPeerOptions } from '@dxos/rpc';\n\nimport { ExtensionContext, TeleportExtension } from './teleport';\n\nexport abstract class RpcExtension<Client, Server> implements TeleportExtension {\n private _extensionContext!: ExtensionContext;\n private _rpc?: ProtoRpcPeer<Client>;\n\n private _isClosed = false;\n\n constructor(private readonly _rpcParams: Omit<ProtoRpcPeerOptions<Client, Server>, 'port' | 'handlers'>) {}\n\n get initiator() {\n return this._extensionContext.initiator;\n }\n\n get localPeerId() {\n return this._extensionContext.localPeerId;\n }\n\n get remotePeerId() {\n return this._extensionContext.remotePeerId;\n }\n\n get rpc(): Client {\n assert(this._rpc);\n return this._rpc.rpc;\n }\n\n protected abstract getHandlers(): Promise<Server>;\n\n async onOpen(context: ExtensionContext): Promise<void> {\n this._extensionContext = context;\n\n const handlers = await this.getHandlers();\n\n if (this._isClosed) {\n return;\n }\n\n const port = context.createPort('rpc', {\n contentType: 'application/x-protobuf; messageType=\"dxos.rpc.Message\"'\n });\n this._rpc = createProtoRpcPeer({\n ...this._rpcParams,\n handlers,\n port\n });\n\n await this._rpc.open();\n }\n\n async onClose(err?: Error | undefined): Promise<void> {\n this._isClosed = true;\n await this._rpc?.close();\n }\n\n close() {\n this._extensionContext.close();\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["Framer", "_stream", "Duplex", "objectMode", "read", "write", "chunk", "encoding", "callback", "assert", "_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", "varint", "encode", "set", "import_node_assert", "import_node_stream", "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", "import_node_assert", "import_async", "import_debug", "import_log", "import_protocols", "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", "assert", "PublicKey", "isPublicKey", "onExtensionRegistered", "set", "name", "has", "add", "_openExtension", "stream", "on", "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", "import_node_assert", "import_async", "import_log", "import_protocols", "import_rpc", "TestExtension", "constructor", "callbacks", "open", "Trigger", "closed", "remotePeerId", "extensionContext", "onOpen", "context", "log", "localPeerId", "_rpc", "createProtoRpcPeer", "port", "createPort", "contentType", "requested", "TestService", "schema", "getService", "exposed", "handlers", "voidCall", "request", "testCall", "data", "timeout", "wake", "onClose", "err", "close", "test", "wait", "res", "asyncTimeout", "rpc", "assert", "import_node_assert", "import_rpc", "RpcExtension", "constructor", "_rpcParams", "_isClosed", "initiator", "_extensionContext", "localPeerId", "remotePeerId", "rpc", "assert", "_rpc", "onOpen", "context", "handlers", "getHandlers", "port", "createPort", "contentType", "createProtoRpcPeer", "open", "onClose", "err", "close"]
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nexport * from './muxing';\nexport * from './teleport';\nexport * from './testing/test-extension';\nexport * from './rpc-extension';\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';\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 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 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 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: 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 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(message = 'test') {\n await this.open.wait({ timeout: 500 });\n const res = await asyncTimeout(this._rpc.rpc.TestService.testCall({ data: message }), 500);\n assert(res.data === message);\n }\n\n /**\n * Force-close the connection.\n */\n async closeConnection(err?: Error) {\n this.extensionContext?.close(err);\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\n\nimport { createProtoRpcPeer, ProtoRpcPeer, ProtoRpcPeerOptions } from '@dxos/rpc';\n\nimport { ExtensionContext, TeleportExtension } from './teleport';\n\nexport abstract class RpcExtension<Client, Server> implements TeleportExtension {\n private _extensionContext!: ExtensionContext;\n private _rpc?: ProtoRpcPeer<Client>;\n\n private _isClosed = false;\n\n constructor(private readonly _rpcParams: Omit<ProtoRpcPeerOptions<Client, Server>, 'port' | 'handlers'>) {}\n\n get initiator() {\n return this._extensionContext.initiator;\n }\n\n get localPeerId() {\n return this._extensionContext.localPeerId;\n }\n\n get remotePeerId() {\n return this._extensionContext.remotePeerId;\n }\n\n get rpc(): Client {\n assert(this._rpc);\n return this._rpc.rpc;\n }\n\n protected abstract getHandlers(): Promise<Server>;\n\n async onOpen(context: ExtensionContext): Promise<void> {\n this._extensionContext = context;\n\n const handlers = await this.getHandlers();\n\n if (this._isClosed) {\n return;\n }\n\n const port = context.createPort('rpc', {\n contentType: 'application/x-protobuf; messageType=\"dxos.rpc.Message\"'\n });\n this._rpc = createProtoRpcPeer({\n ...this._rpcParams,\n handlers,\n port\n });\n\n await this._rpc.open();\n }\n\n async onClose(err?: Error | undefined): Promise<void> {\n this._isClosed = true;\n await this._rpc?.close();\n }\n\n close() {\n this._extensionContext.close();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Framer", "_stream", "Duplex", "objectMode", "read", "write", "chunk", "encoding", "callback", "assert", "_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", "varint", "encode", "set", "import_node_assert", "import_node_stream", "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", "import_node_assert", "import_async", "import_debug", "import_log", "import_protocols", "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", "assert", "PublicKey", "isPublicKey", "onExtensionRegistered", "set", "name", "has", "add", "_openExtension", "stream", "on", "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", "import_node_assert", "import_async", "import_log", "import_protocols", "import_rpc", "TestExtension", "constructor", "callbacks", "open", "Trigger", "closed", "remotePeerId", "extensionContext", "onOpen", "context", "log", "localPeerId", "_rpc", "createProtoRpcPeer", "port", "createPort", "contentType", "requested", "TestService", "schema", "getService", "exposed", "handlers", "voidCall", "request", "testCall", "data", "timeout", "wake", "onClose", "err", "close", "test", "message", "wait", "res", "asyncTimeout", "rpc", "assert", "closeConnection", "import_node_assert", "import_rpc", "RpcExtension", "constructor", "_rpcParams", "_isClosed", "initiator", "_extensionContext", "localPeerId", "remotePeerId", "rpc", "assert", "_rpc", "onOpen", "context", "handlers", "getHandlers", "port", "createPort", "contentType", "createProtoRpcPeer", "open", "onClose", "err", "close"]
|
|
7
7
|
}
|
package/dist/lib/node/meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/core/mesh/teleport/src/muxing/framer.ts":{"bytes":12785,"imports":[{"path":"node:assert","kind":"import-statement","external":true},{"path":"node:stream","kind":"import-statement","external":true},{"path":"varint","kind":"import-statement","external":true}]},"packages/core/mesh/teleport/src/muxing/muxer.ts":{"bytes":25338,"imports":[{"path":"node:assert","kind":"import-statement","external":true},{"path":"node:stream","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport/src/muxing/framer.ts","kind":"import-statement","original":"./framer"}]},"packages/core/mesh/teleport/src/muxing/rpc-port.ts":{"bytes":824,"imports":[]},"packages/core/mesh/teleport/src/muxing/index.ts":{"bytes":539,"imports":[{"path":"packages/core/mesh/teleport/src/muxing/framer.ts","kind":"import-statement","original":"./framer"},{"path":"packages/core/mesh/teleport/src/muxing/muxer.ts","kind":"import-statement","original":"./muxer"},{"path":"packages/core/mesh/teleport/src/muxing/rpc-port.ts","kind":"import-statement","original":"./rpc-port"}]},"packages/core/mesh/teleport/src/teleport.ts":{"bytes":27932,"imports":[{"path":"node:assert","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport/src/muxing/index.ts","kind":"import-statement","original":"./muxing"}]},"packages/core/mesh/teleport/src/testing/test-extension.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/core/mesh/teleport/src/muxing/framer.ts":{"bytes":12785,"imports":[{"path":"node:assert","kind":"import-statement","external":true},{"path":"node:stream","kind":"import-statement","external":true},{"path":"varint","kind":"import-statement","external":true}]},"packages/core/mesh/teleport/src/muxing/muxer.ts":{"bytes":25338,"imports":[{"path":"node:assert","kind":"import-statement","external":true},{"path":"node:stream","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport/src/muxing/framer.ts","kind":"import-statement","original":"./framer"}]},"packages/core/mesh/teleport/src/muxing/rpc-port.ts":{"bytes":824,"imports":[]},"packages/core/mesh/teleport/src/muxing/index.ts":{"bytes":539,"imports":[{"path":"packages/core/mesh/teleport/src/muxing/framer.ts","kind":"import-statement","original":"./framer"},{"path":"packages/core/mesh/teleport/src/muxing/muxer.ts","kind":"import-statement","original":"./muxer"},{"path":"packages/core/mesh/teleport/src/muxing/rpc-port.ts","kind":"import-statement","original":"./rpc-port"}]},"packages/core/mesh/teleport/src/teleport.ts":{"bytes":27932,"imports":[{"path":"node:assert","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/debug","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport/src/muxing/index.ts","kind":"import-statement","original":"./muxing"}]},"packages/core/mesh/teleport/src/testing/test-extension.ts":{"bytes":8458,"imports":[{"path":"node:assert","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/protocols","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}]},"packages/core/mesh/teleport/src/rpc-extension.ts":{"bytes":5055,"imports":[{"path":"node:assert","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}]},"packages/core/mesh/teleport/src/index.ts":{"bytes":685,"imports":[{"path":"packages/core/mesh/teleport/src/muxing/index.ts","kind":"import-statement","original":"./muxing"},{"path":"packages/core/mesh/teleport/src/teleport.ts","kind":"import-statement","original":"./teleport"},{"path":"packages/core/mesh/teleport/src/testing/test-extension.ts","kind":"import-statement","original":"./testing/test-extension"},{"path":"packages/core/mesh/teleport/src/rpc-extension.ts","kind":"import-statement","original":"./rpc-extension"}]},"packages/core/mesh/teleport/src/testing/test-builder.ts":{"bytes":13440,"imports":[{"path":"node:assert","kind":"import-statement","external":true},{"path":"node:stream","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"packages/core/mesh/teleport/src/teleport.ts","kind":"import-statement","original":"../teleport"}]},"packages/core/mesh/teleport/src/testing/index.ts":{"bytes":494,"imports":[{"path":"packages/core/mesh/teleport/src/testing/test-builder.ts","kind":"import-statement","original":"./test-builder"},{"path":"packages/core/mesh/teleport/src/testing/test-extension.ts","kind":"import-statement","original":"./test-extension"}]}},"outputs":{"packages/core/mesh/teleport/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":39410},"packages/core/mesh/teleport/dist/lib/node/index.cjs":{"imports":[{"path":"node:assert","kind":"require-call","external":true},{"path":"node:stream","kind":"require-call","external":true},{"path":"varint","kind":"require-call","external":true},{"path":"node:assert","kind":"require-call","external":true},{"path":"node:stream","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/debug","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"@dxos/protocols","kind":"require-call","external":true},{"path":"node:assert","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/context","kind":"require-call","external":true},{"path":"@dxos/debug","kind":"require-call","external":true},{"path":"@dxos/keys","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"@dxos/protocols","kind":"require-call","external":true},{"path":"@dxos/rpc","kind":"require-call","external":true},{"path":"@dxos/util","kind":"require-call","external":true},{"path":"node:assert","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"@dxos/protocols","kind":"require-call","external":true},{"path":"@dxos/rpc","kind":"require-call","external":true},{"path":"node:assert","kind":"require-call","external":true},{"path":"@dxos/rpc","kind":"require-call","external":true}],"exports":[],"entryPoint":"packages/core/mesh/teleport/src/index.ts","inputs":{"packages/core/mesh/teleport/src/index.ts":{"bytesInOutput":309},"packages/core/mesh/teleport/src/muxing/framer.ts":{"bytesInOutput":2736},"packages/core/mesh/teleport/src/muxing/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport/src/muxing/muxer.ts":{"bytesInOutput":5952},"packages/core/mesh/teleport/src/teleport.ts":{"bytesInOutput":7897},"packages/core/mesh/teleport/src/testing/test-extension.ts":{"bytesInOutput":2486},"packages/core/mesh/teleport/src/rpc-extension.ts":{"bytesInOutput":1144}},"bytes":22452},"packages/core/mesh/teleport/dist/lib/node/testing/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":43726},"packages/core/mesh/teleport/dist/lib/node/testing/index.cjs":{"imports":[{"path":"node:assert","kind":"require-call","external":true},{"path":"node:stream","kind":"require-call","external":true},{"path":"@dxos/keys","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"node:assert","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/context","kind":"require-call","external":true},{"path":"@dxos/debug","kind":"require-call","external":true},{"path":"@dxos/keys","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"@dxos/protocols","kind":"require-call","external":true},{"path":"@dxos/rpc","kind":"require-call","external":true},{"path":"@dxos/util","kind":"require-call","external":true},{"path":"node:assert","kind":"require-call","external":true},{"path":"node:stream","kind":"require-call","external":true},{"path":"varint","kind":"require-call","external":true},{"path":"node:assert","kind":"require-call","external":true},{"path":"node:stream","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/debug","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"@dxos/protocols","kind":"require-call","external":true},{"path":"node:assert","kind":"require-call","external":true},{"path":"@dxos/async","kind":"require-call","external":true},{"path":"@dxos/log","kind":"require-call","external":true},{"path":"@dxos/protocols","kind":"require-call","external":true},{"path":"@dxos/rpc","kind":"require-call","external":true}],"exports":[],"entryPoint":"packages/core/mesh/teleport/src/testing/index.ts","inputs":{"packages/core/mesh/teleport/src/testing/index.ts":{"bytesInOutput":245},"packages/core/mesh/teleport/src/testing/test-builder.ts":{"bytesInOutput":3843},"packages/core/mesh/teleport/src/teleport.ts":{"bytesInOutput":7897},"packages/core/mesh/teleport/src/muxing/framer.ts":{"bytesInOutput":2736},"packages/core/mesh/teleport/src/muxing/index.ts":{"bytesInOutput":0},"packages/core/mesh/teleport/src/muxing/muxer.ts":{"bytesInOutput":5952},"packages/core/mesh/teleport/src/testing/test-extension.ts":{"bytesInOutput":2486}},"bytes":25178}}}
|
|
@@ -800,14 +800,21 @@ var TestExtension = class {
|
|
|
800
800
|
this.closed.wake();
|
|
801
801
|
await ((_c = this._rpc) == null ? void 0 : _c.close());
|
|
802
802
|
}
|
|
803
|
-
async test() {
|
|
803
|
+
async test(message = "test") {
|
|
804
804
|
await this.open.wait({
|
|
805
805
|
timeout: 500
|
|
806
806
|
});
|
|
807
807
|
const res = await (0, import_async3.asyncTimeout)(this._rpc.rpc.TestService.testCall({
|
|
808
|
-
data:
|
|
808
|
+
data: message
|
|
809
809
|
}), 500);
|
|
810
|
-
(0, import_node_assert5.default)(res.data ===
|
|
810
|
+
(0, import_node_assert5.default)(res.data === message);
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Force-close the connection.
|
|
814
|
+
*/
|
|
815
|
+
async closeConnection(err) {
|
|
816
|
+
var _a;
|
|
817
|
+
(_a = this.extensionContext) == null ? void 0 : _a.close(err);
|
|
811
818
|
}
|
|
812
819
|
};
|
|
813
820
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/testing/index.ts", "../../../../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\nexport * from './test-builder';\nexport * from './test-extension';\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\nimport { Duplex, pipeline } from 'node:stream';\n\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { Teleport } from '../teleport';\n\ntype CreatePeerOpts<T extends TestPeer> = {\n factory: () => T;\n};\n\nexport class TestBuilder {\n private readonly _peers = new Set<TestPeer>();\n\n createPeer<T extends TestPeer>(opts: CreatePeerOpts<T>): T {\n const peer = opts.factory();\n this._peers.add(peer);\n return peer;\n }\n\n *createPeers<T extends TestPeer>(opts: CreatePeerOpts<T>): Generator<T> {\n while (true) {\n yield this.createPeer(opts);\n }\n }\n\n async destroy() {\n await Promise.all(Array.from(this._peers).map((agent) => agent.destroy()));\n }\n\n async connect(peer1: TestPeer, peer2: TestPeer) {\n assert(peer1 !== peer2);\n assert(this._peers.has(peer1));\n assert(this._peers.has(peer1));\n\n const connection1 = peer1.createConnection({ initiator: true, remotePeerId: peer2.peerId });\n const connection2 = peer2.createConnection({ initiator: false, remotePeerId: peer1.peerId });\n\n pipeStreams(connection1.teleport.stream, connection2.teleport.stream);\n await Promise.all([peer1.openConnection(connection1), peer2.openConnection(connection2)]);\n\n return [connection1, connection2];\n }\n\n async disconnect(peer1: TestPeer, peer2: TestPeer) {\n assert(peer1 !== peer2);\n assert(this._peers.has(peer1));\n assert(this._peers.has(peer1));\n\n const connection1 = Array.from(peer1.connections).find((connection) =>\n connection.remotePeerId.equals(peer2.peerId)\n );\n const connection2 = Array.from(peer2.connections).find((connection) =>\n connection.remotePeerId.equals(peer1.peerId)\n );\n\n assert(connection1);\n assert(connection2);\n\n await Promise.all([peer1.closeConnection(connection1), peer2.closeConnection(connection2)]);\n }\n}\n\nexport class TestPeer {\n public readonly connections = new Set<TestConnection>();\n\n constructor(public readonly peerId: PublicKey = PublicKey.random()) {}\n\n protected async onOpen(connection: TestConnection) {}\n protected async onClose(connection: TestConnection) {}\n\n createConnection({ initiator, remotePeerId }: { initiator: boolean; remotePeerId: PublicKey }) {\n const connection = new TestConnection(this.peerId, remotePeerId, initiator);\n this.connections.add(connection);\n return connection;\n }\n\n async openConnection(connection: TestConnection) {\n assert(this.connections.has(connection));\n await connection.teleport.open();\n await this.onOpen(connection);\n }\n\n async closeConnection(connection: TestConnection) {\n assert(this.connections.has(connection));\n await this.onClose(connection);\n await connection.teleport.close();\n this.connections.delete(connection);\n }\n\n async destroy() {\n for (const teleport of this.connections) {\n await this.closeConnection(teleport);\n }\n }\n}\n\nconst pipeStreams = (stream1: Duplex, stream2: Duplex) => {\n pipeline(stream1, stream2, (err) => {\n if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {\n log.catch(err);\n }\n });\n pipeline(stream2, stream1, (err) => {\n if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {\n log.catch(err);\n }\n });\n};\n\nexport class TestConnection {\n public teleport: Teleport;\n\n constructor(\n public readonly localPeerId: PublicKey,\n public readonly remotePeerId: PublicKey,\n public readonly initiator: boolean\n ) {\n this.teleport = new Teleport({\n initiator,\n localPeerId,\n remotePeerId\n });\n }\n}\n", "//\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 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 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 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: 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 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": "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",
|
|
6
|
-
"names": ["import_node_assert", "import_node_stream", "import_keys", "import_log", "import_node_assert", "import_async", "import_debug", "import_log", "import_protocols", "Framer", "_stream", "Duplex", "objectMode", "read", "write", "chunk", "encoding", "callback", "assert", "_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", "varint", "encode", "set", "import_node_assert", "import_node_stream", "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", "onTimeout", "Error", "_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", "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", "TestBuilder", "_peers", "Set", "createPeer", "opts", "peer", "factory", "add", "createPeers", "destroy", "Promise", "all", "Array", "from", "map", "agent", "connect", "peer1", "peer2", "assert", "has", "connection1", "createConnection", "initiator", "remotePeerId", "peerId", "connection2", "pipeStreams", "teleport", "stream", "openConnection", "disconnect", "connections", "find", "connection", "equals", "closeConnection", "TestPeer", "constructor", "PublicKey", "random", "onOpen", "onClose", "TestConnection", "open", "close", "delete", "stream1", "stream2", "pipeline", "err", "code", "log", "catch", "localPeerId", "Teleport", "import_node_assert", "import_async", "import_log", "import_protocols", "import_rpc", "TestExtension", "constructor", "callbacks", "open", "Trigger", "closed", "remotePeerId", "extensionContext", "onOpen", "context", "log", "localPeerId", "_rpc", "createProtoRpcPeer", "port", "createPort", "contentType", "requested", "TestService", "schema", "getService", "exposed", "handlers", "voidCall", "request", "testCall", "data", "timeout", "wake", "onClose", "err", "close", "test", "wait", "res", "asyncTimeout", "rpc", "assert"]
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nexport * from './test-builder';\nexport * from './test-extension';\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport assert from 'node:assert';\nimport { Duplex, pipeline } from 'node:stream';\n\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { Teleport } from '../teleport';\n\ntype CreatePeerOpts<T extends TestPeer> = {\n factory: () => T;\n};\n\nexport class TestBuilder {\n private readonly _peers = new Set<TestPeer>();\n\n createPeer<T extends TestPeer>(opts: CreatePeerOpts<T>): T {\n const peer = opts.factory();\n this._peers.add(peer);\n return peer;\n }\n\n *createPeers<T extends TestPeer>(opts: CreatePeerOpts<T>): Generator<T> {\n while (true) {\n yield this.createPeer(opts);\n }\n }\n\n async destroy() {\n await Promise.all(Array.from(this._peers).map((agent) => agent.destroy()));\n }\n\n async connect(peer1: TestPeer, peer2: TestPeer) {\n assert(peer1 !== peer2);\n assert(this._peers.has(peer1));\n assert(this._peers.has(peer1));\n\n const connection1 = peer1.createConnection({ initiator: true, remotePeerId: peer2.peerId });\n const connection2 = peer2.createConnection({ initiator: false, remotePeerId: peer1.peerId });\n\n pipeStreams(connection1.teleport.stream, connection2.teleport.stream);\n await Promise.all([peer1.openConnection(connection1), peer2.openConnection(connection2)]);\n\n return [connection1, connection2];\n }\n\n async disconnect(peer1: TestPeer, peer2: TestPeer) {\n assert(peer1 !== peer2);\n assert(this._peers.has(peer1));\n assert(this._peers.has(peer1));\n\n const connection1 = Array.from(peer1.connections).find((connection) =>\n connection.remotePeerId.equals(peer2.peerId)\n );\n const connection2 = Array.from(peer2.connections).find((connection) =>\n connection.remotePeerId.equals(peer1.peerId)\n );\n\n assert(connection1);\n assert(connection2);\n\n await Promise.all([peer1.closeConnection(connection1), peer2.closeConnection(connection2)]);\n }\n}\n\nexport class TestPeer {\n public readonly connections = new Set<TestConnection>();\n\n constructor(public readonly peerId: PublicKey = PublicKey.random()) {}\n\n protected async onOpen(connection: TestConnection) {}\n protected async onClose(connection: TestConnection) {}\n\n createConnection({ initiator, remotePeerId }: { initiator: boolean; remotePeerId: PublicKey }) {\n const connection = new TestConnection(this.peerId, remotePeerId, initiator);\n this.connections.add(connection);\n return connection;\n }\n\n async openConnection(connection: TestConnection) {\n assert(this.connections.has(connection));\n await connection.teleport.open();\n await this.onOpen(connection);\n }\n\n async closeConnection(connection: TestConnection) {\n assert(this.connections.has(connection));\n await this.onClose(connection);\n await connection.teleport.close();\n this.connections.delete(connection);\n }\n\n async destroy() {\n for (const teleport of this.connections) {\n await this.closeConnection(teleport);\n }\n }\n}\n\nconst pipeStreams = (stream1: Duplex, stream2: Duplex) => {\n pipeline(stream1, stream2, (err) => {\n if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {\n log.catch(err);\n }\n });\n pipeline(stream2, stream1, (err) => {\n if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {\n log.catch(err);\n }\n });\n};\n\nexport class TestConnection {\n public teleport: Teleport;\n\n constructor(\n public readonly localPeerId: PublicKey,\n public readonly remotePeerId: PublicKey,\n public readonly initiator: boolean\n ) {\n this.teleport = new Teleport({\n initiator,\n localPeerId,\n remotePeerId\n });\n }\n}\n", "//\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 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 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 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: 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 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(message = 'test') {\n await this.open.wait({ timeout: 500 });\n const res = await asyncTimeout(this._rpc.rpc.TestService.testCall({ data: message }), 500);\n assert(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": ["import_node_assert", "import_node_stream", "import_keys", "import_log", "import_node_assert", "import_async", "import_debug", "import_log", "import_protocols", "Framer", "_stream", "Duplex", "objectMode", "read", "write", "chunk", "encoding", "callback", "assert", "_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", "varint", "encode", "set", "import_node_assert", "import_node_stream", "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", "onTimeout", "Error", "_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", "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", "TestBuilder", "_peers", "Set", "createPeer", "opts", "peer", "factory", "add", "createPeers", "destroy", "Promise", "all", "Array", "from", "map", "agent", "connect", "peer1", "peer2", "assert", "has", "connection1", "createConnection", "initiator", "remotePeerId", "peerId", "connection2", "pipeStreams", "teleport", "stream", "openConnection", "disconnect", "connections", "find", "connection", "equals", "closeConnection", "TestPeer", "constructor", "PublicKey", "random", "onOpen", "onClose", "TestConnection", "open", "close", "delete", "stream1", "stream2", "pipeline", "err", "code", "log", "catch", "localPeerId", "Teleport", "import_node_assert", "import_async", "import_log", "import_protocols", "import_rpc", "TestExtension", "constructor", "callbacks", "open", "Trigger", "closed", "remotePeerId", "extensionContext", "onOpen", "context", "log", "localPeerId", "_rpc", "createProtoRpcPeer", "port", "createPort", "contentType", "requested", "TestService", "schema", "getService", "exposed", "handlers", "voidCall", "request", "testCall", "data", "timeout", "wake", "onClose", "err", "close", "test", "message", "wait", "res", "asyncTimeout", "rpc", "assert", "closeConnection"]
|
|
7
7
|
}
|
|
@@ -14,7 +14,11 @@ export declare class TestExtension implements TeleportExtension {
|
|
|
14
14
|
get remotePeerId(): import("@dxos/keys").PublicKey | undefined;
|
|
15
15
|
onOpen(context: ExtensionContext): Promise<void>;
|
|
16
16
|
onClose(err?: Error): Promise<void>;
|
|
17
|
-
test(): Promise<void>;
|
|
17
|
+
test(message?: string): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Force-close the connection.
|
|
20
|
+
*/
|
|
21
|
+
closeConnection(err?: Error): Promise<void>;
|
|
18
22
|
}
|
|
19
23
|
export {};
|
|
20
24
|
//# sourceMappingURL=test-extension.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-extension.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-extension.ts"],"names":[],"mappings":"AAMA,OAAO,EAAgB,OAAO,EAAE,MAAM,aAAa,CAAC;AAMpD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAElE,UAAU,sBAAsB;IAC9B,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,qBAAa,aAAc,YAAW,iBAAiB;aAMzB,SAAS,EAAE,sBAAsB;IAL7D,SAAgB,IAAI,gBAAiB;IACrC,SAAgB,MAAM,gBAAiB;IAChC,gBAAgB,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACtD,OAAO,CAAC,IAAI,CAA8C;gBAE9B,SAAS,GAAE,sBAA2B;IAElE,IAAI,YAAY,+CAEf;IAEK,MAAM,CAAC,OAAO,EAAE,gBAAgB;IAkChC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK;IAOnB,IAAI;
|
|
1
|
+
{"version":3,"file":"test-extension.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-extension.ts"],"names":[],"mappings":"AAMA,OAAO,EAAgB,OAAO,EAAE,MAAM,aAAa,CAAC;AAMpD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAElE,UAAU,sBAAsB;IAC9B,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,qBAAa,aAAc,YAAW,iBAAiB;aAMzB,SAAS,EAAE,sBAAsB;IAL7D,SAAgB,IAAI,gBAAiB;IACrC,SAAgB,MAAM,gBAAiB;IAChC,gBAAgB,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACtD,OAAO,CAAC,IAAI,CAA8C;gBAE9B,SAAS,GAAE,sBAA2B;IAElE,IAAI,YAAY,+CAEf;IAEK,MAAM,CAAC,OAAO,EAAE,gBAAgB;IAkChC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK;IAOnB,IAAI,CAAC,OAAO,SAAS;IAM3B;;OAEG;IACG,eAAe,CAAC,GAAG,CAAC,EAAE,KAAK;CAGlC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/teleport",
|
|
3
|
-
"version": "0.1.31
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"description": "Stream muxer.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -22,21 +22,21 @@
|
|
|
22
22
|
"debug": "^4.3.3",
|
|
23
23
|
"randombytes": "^2.1.0",
|
|
24
24
|
"varint": "6.0.0",
|
|
25
|
-
"@dxos/context": "0.1.31
|
|
26
|
-
"@dxos/debug": "0.1.31
|
|
27
|
-
"@dxos/keys": "0.1.31
|
|
28
|
-
"@dxos/log": "0.1.31
|
|
29
|
-
"@dxos/node-std": "0.1.31
|
|
30
|
-
"@dxos/protocols": "0.1.31
|
|
31
|
-
"@dxos/rpc": "0.1.31
|
|
32
|
-
"@dxos/util": "0.1.31
|
|
25
|
+
"@dxos/context": "0.1.31",
|
|
26
|
+
"@dxos/debug": "0.1.31",
|
|
27
|
+
"@dxos/keys": "0.1.31",
|
|
28
|
+
"@dxos/log": "0.1.31",
|
|
29
|
+
"@dxos/node-std": "0.1.31",
|
|
30
|
+
"@dxos/protocols": "0.1.31",
|
|
31
|
+
"@dxos/rpc": "0.1.31",
|
|
32
|
+
"@dxos/util": "0.1.31"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/randombytes": "^2.0.0",
|
|
36
36
|
"@types/varint": "6.0.0",
|
|
37
37
|
"typescript": "^4.8.4",
|
|
38
38
|
"wait-for-expect": "^3.0.2",
|
|
39
|
-
"@dxos/async": "0.1.31
|
|
39
|
+
"@dxos/async": "0.1.31"
|
|
40
40
|
},
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"access": "public"
|
|
@@ -70,9 +70,16 @@ export class TestExtension implements TeleportExtension {
|
|
|
70
70
|
await this._rpc?.close();
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
async test() {
|
|
73
|
+
async test(message = 'test') {
|
|
74
74
|
await this.open.wait({ timeout: 500 });
|
|
75
|
-
const res = await asyncTimeout(this._rpc.rpc.TestService.testCall({ data:
|
|
76
|
-
assert(res.data ===
|
|
75
|
+
const res = await asyncTimeout(this._rpc.rpc.TestService.testCall({ data: message }), 500);
|
|
76
|
+
assert(res.data === message);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Force-close the connection.
|
|
81
|
+
*/
|
|
82
|
+
async closeConnection(err?: Error) {
|
|
83
|
+
this.extensionContext?.close(err);
|
|
77
84
|
}
|
|
78
85
|
}
|