UNPKG

@libp2p/mplex

Version:

JavaScript implementation of https://github.com/libp2p/mplex

87 lines 3.06 kB
import { AbstractStream } from '@libp2p/utils'; import { Uint8ArrayList } from 'uint8arraylist'; import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'; import { MAX_MSG_SIZE } from "./decode.js"; import { encode } from "./encode.js"; import { InitiatorMessageTypes, ReceiverMessageTypes } from "./message-types.js"; export class MplexStream extends AbstractStream { streamId; types; maxDataSize; muxer; constructor(init) { super(init); this.types = init.direction === 'outbound' ? InitiatorMessageTypes : ReceiverMessageTypes; this.maxDataSize = init.maxDataSize; this.muxer = init.muxer; this.streamId = parseInt(this.id.substring(1)); if (init.direction === 'outbound') { // open the stream on the receiver end. do this in a microtask so the // stream gets added to the streams array by the muxer superclass before // we send the NEW_STREAM message, otherwise we create a race condition // whereby we can receive the stream messages before the stream is added // to the streams list queueMicrotask(() => { this.muxer.send(encode({ id: this.streamId, type: InitiatorMessageTypes.NEW_STREAM, data: new Uint8ArrayList(uint8ArrayFromString(this.id)) })); }); } } sendData(data) { const list = new Uint8ArrayList(); const sentBytes = data.byteLength; while (data.byteLength > 0) { const toSend = Math.min(data.byteLength, this.maxDataSize); const slice = data.sublist(0, toSend); data = data.sublist(toSend); list.append(encode({ id: this.streamId, type: this.types.MESSAGE, data: slice })); } return { sentBytes, canSendMore: this.muxer.send(list) }; } sendReset() { return this.muxer.send(encode({ id: this.streamId, type: this.types.RESET })); } async sendCloseWrite(options) { this.muxer.send(encode({ id: this.streamId, type: this.types.CLOSE })); options?.signal?.throwIfAborted(); } async sendCloseRead(options) { options?.signal?.throwIfAborted(); // mplex does not support close read, only close write } sendPause() { // mplex does not support backpressure } sendResume() { // mplex does not support backpressure } } export function createStream(options) { const { id, muxer, direction, maxMsgSize = MAX_MSG_SIZE } = options; return new MplexStream({ ...options, id: direction === 'outbound' ? (`i${id}`) : `r${id}`, direction, maxDataSize: maxMsgSize, muxer, log: options.log.newScope(`${direction}:${id}`), protocol: '' }); } //# sourceMappingURL=stream.js.map