/** * WritableStreamDefaultWriter that multiplexes writes to multiple underlying writers. * * FanoutWriteStream broadcasts all write operations to an array of writers simultaneously. * All operations (write, close, abort, releaseLock) are applied to all underlying writers. * Useful for scenarios like logging to multiple destinations, streaming to multiple * consumers, or maintaining redundant copies of stream data. * * @example * ```typescript * // Write to both file and console simultaneously * const fileStream = new WritableStream({ ... }); * const consoleStream = new ConsoleWriterStream(); * * const fanout = new FanoutWriteStream([ * fileStream.getWriter(), * consoleStream.getWriter() * ]); * * // This writes to both destinations * await fanout.write(new TextEncoder().encode('Log message')); * * // Close all writers * await fanout.close(); * ``` * * @example * ```typescript * // Mirror stream data to multiple endpoints * const backupWriter = backupStream.getWriter(); * const primaryWriter = primaryStream.getWriter(); * const metricsWriter = metricsStream.getWriter(); * * const fanout = new FanoutWriteStream([ * primaryWriter, * backupWriter, * metricsWriter * ]); * * // All three streams receive the data * for (const chunk of dataChunks) { * await fanout.write(chunk); * } * ``` */ export class FanoutWriteStream implements WritableStreamDefaultWriter { readonly _writers: WritableStreamDefaultWriter[]; readonly ready: Promise; readonly closed: Promise; readonly desiredSize: number | null = null; constructor(writers: WritableStreamDefaultWriter[]) { this._writers = writers; this.ready = Promise.all(this._writers.map((w) => w.ready)) as Promise; this.closed = Promise.all(this._writers.map((w) => w.closed)) as Promise; } abort(reason?: unknown): Promise { return Promise.all(this._writers.map((w) => w.abort(reason))).then(() => { /* do nothing */ }); } close(): Promise { return Promise.all(this._writers.map((w) => w.close())).then(() => { /* do nothing */ }); } releaseLock(): void { this._writers.map((w) => w.releaseLock()); } write(chunk?: Uint8Array): Promise { return Promise.all(this._writers.map((w) => w.write(chunk))).then(() => { /* do nothing */ }); } }