UNPKG

@chainsafe/libp2p-quic

Version:
106 lines 3.42 kB
import { raceSignal } from 'race-signal'; import { QuicStream } from './stream.js'; /** * Each stream muxer factory is only configured for a single connection */ export class QuicStreamMuxerFactory { #connection; init; protocol = 'quic'; constructor(init) { this.#connection = init.connection; this.init = init; } createStreamMuxer(init) { return new QuicStreamMuxer({ ...init, connection: this.#connection, logger: this.init.logger }); } } class QuicStreamMuxer { id; #connection; init; log; protocol = 'quic'; streams = []; source = (async function* () { })(); sink = async function* () { }; controller = new AbortController(); constructor(init) { this.id = init.connection.id(); this.#connection = init.connection; this.init = init; this.log = init.logger.forComponent('libp2p:quic:muxer'); void this.awaitInboundStreams(); this.log('new', this.id); } async awaitInboundStreams() { while (true) { try { const stream = await raceSignal(this.#connection.inboundStream(), this.controller.signal); this.onInboundStream(stream); } catch (e) { this.log.error('%s error accepting stream - %e', this.id, e); if (this.controller.signal.aborted) { break; } } } this.log('%s no longer awaiting inbound streams', this.id); } onInboundStream = (str) => { const stream = new QuicStream({ id: str.id(), stream: str, direction: 'inbound', log: this.init.logger.forComponent(`libp2p:quic:stream:${this.#connection.id()}:${str.id()}:inbound`), onEnd: () => { const index = this.streams.findIndex(s => s === stream); if (index !== -1) { this.streams.splice(index, 1); } this.init.onStreamEnd?.(stream); } }); this.streams.push(stream); this.init.onIncomingStream?.(stream); }; async newStream(name) { const str = await this.#connection.outboundStream(); this.controller.signal.throwIfAborted(); const stream = new QuicStream({ id: str.id(), stream: str, direction: 'outbound', log: this.init.logger.forComponent(`libp2p:quic:stream:${this.#connection.id()}:${str.id()}:outbound`), onEnd: () => { const index = this.streams.findIndex(s => s === stream); if (index !== -1) { this.streams.splice(index, 1); } this.init.onStreamEnd?.(stream); } }); this.streams.push(stream); return stream; } async close(options) { this.controller.abort(); await Promise.all(this.streams.map(async (stream) => stream.close(options))); this.streams = []; this.log('%s closed', this.id); } abort(err) { this.controller.abort(); for (const stream of this.streams) { stream.abort(err); } this.streams = []; this.log('%s aborted', this.id); } } //# sourceMappingURL=stream-muxer.js.map