import type { LogContext } from '@rocicorp/logger';
import { Readable, type DuplexOptions } from 'node:stream';
import { type WebSocket } from 'ws';
import { type JSONValue } from '../../../shared/src/bigint-json.ts';
import * as v from '../../../shared/src/valita.ts';
import { Subscription, type Options } from './subscription.ts';
export type Source<T> = AsyncIterable<T> & {
    /**
     * Immediately terminates all current iterations (i.e. {@link AsyncIterator.next next()})
     * will return `{value: undefined, done: true}`), and prevents any subsequent iterations
     * from yielding any values.
     *
     * @param err Terminate the iteration by throwing the `err` instead.
     */
    cancel: (err?: Error) => void;
    /**
     * The presence of a `pipeline` iterable allows the usual "consumed-on-iterate" semantics
     * to be overridden.
     *
     * This is suitable for transport layers that serialize messages across processes, such
     * as the {@link streamOut()} method; pipelining allows the transport to send messages
     * as they arrive without waiting for the previous message to be acked, streaming
     * them to the receiving process where they are presumably queued and processed without
     * a per-message ack delay. The receiving end of the transport then responds with acks
     * asynchronously as the receiving end processes the messages.
     */
    pipeline?: AsyncIterable<{
        value: T;
        consumed: () => void;
    }> | undefined;
};
export type Sink<T> = {
    push(message: T): void;
};
/**
 * Back-pressure-aware transformation of a WebSocket into
 * upstream and downstream {@link Subscription} objects.
 */
export declare function stream<In extends JSONValue, Out extends JSONValue>(lc: LogContext, ws: WebSocket, inSchema: v.Type<In>, outOptions?: Options<Out>, inOptions?: Options<In>, streamOptions?: DuplexOptions): {
    outstream: Sink<Out>;
    instream: Source<In>;
};
type PipeOptions<T> = {
    source: Readable;
    sink: Subscription<T>;
    parse: (buffer: Buffer) => T | null;
    bufferMessages?: number;
};
export declare function pipe<T>({ source, sink, parse, bufferMessages }: PipeOptions<T>): void;
export declare function streamOut<T extends JSONValue>(lc: LogContext, source: Source<T>, sink: WebSocket): Promise<void>;
export declare function streamIn<T extends JSONValue>(lc: LogContext, source: WebSocket, schema: v.Type<T>): Promise<Source<T>>;
export {};
//# sourceMappingURL=streams.d.ts.map