import EventEmitter, { EventMap } from 'bare-events' import Buffer, { BufferEncoding } from 'bare-buffer' type StreamEncoding = BufferEncoding | 'buffer' interface StreamCallback { (err: Error | null): void } interface StreamEvents extends EventMap { close: [] error: [err: Error] } interface StreamOptions { eagerOpen?: boolean signal?: AbortSignal open?(this: S, cb: StreamCallback): void predestroy?(this: S): void destroy?(this: S, err: Error | null, cb: StreamCallback): void } interface Stream extends EventEmitter { _open(cb: StreamCallback): void _predestroy(): void _destroy(err: Error | null, cb: StreamCallback): void readonly readable: boolean readonly writable: boolean readonly destroyed: boolean readonly destroying: boolean destroy(err?: Error | null): void } declare class Stream {} interface ReadableEvents extends StreamEvents { data: [data: unknown] end: [] readable: [] piping: [dest: Writable] } interface ReadableOptions extends StreamOptions { encoding?: BufferEncoding highWaterMark?: number read?(this: S, size: number): void } interface Readable extends Stream, AsyncIterable { _read(size: number): void push(data: unknown | null, encoding?: BufferEncoding): boolean unshift(data: unknown | null, encoding?: BufferEncoding): boolean read(): unknown | null resume(): this pause(): this pipe(dest: S, cb?: StreamCallback): S setEncoding(encoding: BufferEncoding): void } declare class Readable< M extends ReadableEvents = ReadableEvents > extends Stream { constructor(opts?: ReadableOptions) static from( data: unknown | unknown[] | AsyncIterable, opts?: ReadableOptions ): Readable static isBackpressured(rs: Readable): boolean static isPaused(rs: Readable): boolean } interface WritableEvents extends StreamEvents { drain: [] finish: [] pipe: [src: Readable] } interface WritableOptions extends StreamOptions { write?( this: S, data: unknown, encoding: StreamEncoding, cb: StreamCallback ): void writev?( this: S, batch: { chunk: unknown; encoding: StreamEncoding }[], cb: StreamCallback ): void final?(this: S, cb: StreamCallback): void } interface Writable extends Stream { _write(data: unknown, encoding: StreamEncoding, cb: StreamCallback): void _writev( batch: { chunk: unknown; encoding: StreamEncoding }[], cb: StreamCallback ): void _final(cb: StreamCallback): void readonly destroyed: boolean write(data: unknown, encoding?: BufferEncoding, cb?: StreamCallback): boolean write(data: unknown, cb?: StreamCallback): boolean end(cb?: StreamCallback): this end(data: unknown, encoding?: BufferEncoding, cb?: StreamCallback): this end(data: unknown, cb?: StreamCallback): this cork(): void uncork(): void } declare class Writable< M extends WritableEvents = WritableEvents > extends Stream { constructor(opts?: WritableOptions) static isBackpressured(ws: Writable): boolean static drained(ws: Writable): Promise } interface DuplexEvents extends ReadableEvents, WritableEvents {} interface DuplexOptions extends ReadableOptions, WritableOptions {} interface Duplex extends Readable, Writable {} declare class Duplex extends Stream { constructor(opts?: DuplexOptions) } interface TransformEvents extends DuplexEvents {} interface TransformOptions extends DuplexOptions { transform?( this: S, data: unknown, encoding: StreamEncoding, cb: StreamCallback ): void flush?(this: S, cb: StreamCallback): void } interface Transform extends Duplex { _transform(data: unknown, encoding: StreamEncoding, cb: StreamCallback): void _flush(cb: StreamCallback): void } declare class Transform< M extends TransformEvents = TransformEvents > extends Duplex { constructor(opts?: TransformOptions) } type Pipeline = [ src: Readable, ...transforms: Duplex[], dest: S ] declare namespace Stream { export { Stream, StreamEvents, StreamOptions, Readable, ReadableEvents, ReadableOptions, Writable, WritableEvents, WritableOptions, Duplex, DuplexEvents, DuplexOptions, Transform, TransformEvents, TransformOptions, Transform as PassThrough } export function pipeline( streams: Pipeline, cb?: StreamCallback ): S export function pipeline(...args: Pipeline): S export function pipeline( ...args: [...Pipeline, cb: StreamCallback] ): S export function finished( stream: Stream, opts: { cleanup?: boolean }, cb: StreamCallback ): () => void export function finished(stream: Stream, cb: StreamCallback): () => void export function isStream(stream: unknown): stream is Stream export function isEnded(stream: Stream): boolean export function isFinished(stream: Stream): boolean export function isDisturbed(stream: Stream): boolean export function getStreamError( stream: Stream, opts?: { all?: boolean } ): Error | null } export = Stream