import { Duplex } from 'stream';
declare const ByteStreamInfo: unique symbol;
interface IByteStreamInfo {
    receivers: Map<number, SrpcByteStream>;
    senders: Map<number, SrpcByteStream>;
    nextId: number;
    step: number;
    pendingReceivers?: Map<number, IPendingReceiver>;
}
interface IPendingReceiver {
    chunks: Buffer[];
    bytes: number;
    finished: boolean;
    destroyedError?: Error;
    timeout?: NodeJS.Timeout;
}
export interface IByteStream {
    [ByteStreamInfo]?: IByteStreamInfo;
    write(streamId: number, data: any): boolean;
    finish(streamId: number): void;
    destroy(streamId: number, err?: any): void;
    attachDisconnectHandler(handler: () => void): void;
    detachDisconnectHandler(handler: () => void): void;
    getBufferedAmount(): number;
    parentStreamId: string;
}
export interface IByteStreamable {
    byteStream: IByteStream;
}
export declare class SrpcByteStream extends Duplex {
    private _id;
    private stream;
    private parentStreamId;
    private isSender;
    private isLocallyDestroyed;
    private isRemotelyDestroyed;
    private drainCallbacks;
    private waitingForDrain;
    get id(): number;
    constructor(stream: IByteStreamable, id?: number);
    static init(stream: IByteStreamable, options: {
        startId: number;
        step: number;
    }): void;
    static createReceiver(stream: IByteStreamable, id: number): SrpcByteStream;
    static createSender(stream: IByteStreamable): SrpcByteStream;
    static writeReceiver(stream: IByteStreamable, id: number, data: any): void;
    static finishReceiver(stream: IByteStreamable, id: number): void;
    /**
     * Handle a destroy signal from the remote side.
     * Checks both receivers and senders maps to support bidirectional abort:
     * - If found in receivers: remote sender is aborting, destroy local receiver
     * - If found in senders: remote receiver is aborting, destroy local sender
     */
    static destroySubstream(stream: IByteStreamable, id: number, err?: string): void;
    private handleDisconnect;
    private cleanup;
    private pollForDrain;
    _read(_size: number): void;
    _write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void;
    _final(callback: (error?: Error | null) => void): void;
    _destroy(error: Error | null, callback: (error?: Error | null) => void): void;
}
export {};
export declare type __ΩIByteStream = any[];
export declare type __ΩIByteStreamable = any[];
//# sourceMappingURL=SrpcByteStream.d.ts.map