UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

70 lines • 2.26 kB
import { ConcurrencyLimiter } from "../concurrency/limiter.js"; import { CHUNK_SIZE } from "./cooperative.js"; import { BytePipe, CAPACITY } from "./pipe.js"; /** One ordered output reader, sharing the byte pipe's capacity and chunks. */ export class OutputPipe { pipe; streams = []; lock = new ConcurrencyLimiter(1); reading = false; constructor(capacity = CAPACITY) { this.pipe = new BytePipe(capacity); } get bufferedBytes() { return this.pipe.bufferedBytes; } get closedReader() { return this.pipe.closedReader; } /** Accept one write in order, waiting for byte capacity. Empty writes have no event. */ async write(stream, data) { const release = await this.lock.acquire(); try { for (let offset = 0; offset < data.byteLength; offset += CHUNK_SIZE) { this.streams.push(stream); try { await this.pipe.write(data.subarray(offset, offset + CHUNK_SIZE)); } catch (error) { this.streams.pop(); throw error; } } } finally { release(); } } /** End output, preserving accepted events before a late failure. */ end(error) { this.pipe.end(error); } async drain() { await this.pipe.drain(); } /** Discard unread output and wake pending readers and writers. */ closeReader() { this.pipe.closeReader(); this.streams.length = 0; } /** Read once; close the reader before closing a pending iterator pull. */ async *events() { if (this.reading) throw new Error('output pipe already has a reader'); this.reading = true; try { for await (const data of this.pipe.stream()) { if (this.closedReader) return; const stream = this.streams.shift(); if (stream === undefined) throw new Error('output stream is missing'); yield { stream, data }; } } finally { this.closeReader(); } } } //# sourceMappingURL=output.js.map