/**
 * In-process Transport pair that models real network conditions.
 *
 * Each `send` samples loss probability against the live `config`; survivors
 * are queued for delivery at `now + latency + jitter` and {@link tick} drains
 * anything past its deadline. Reorder happens naturally when jitter is high
 * relative to send rate.
 *
 * Sister to {@link LoopbackTransport}. Loopback is for unit tests where you
 * want deterministic, manual `deliver_all` control. SimulatedTransport is for
 * prototypes and stress tests where you want realistic-feeling behaviour
 * driven by wall-clock time.
 *
 * Pair two instances with {@link bind_pair}; each becomes the other's delivery
 * target. The `config` object is mutable at runtime — sliders in dev tools
 * can poke at it freely.
 *
 * @author Alex Goldring
 * @copyright Company Named Limited (c) 2025
 */
export class SimulatedTransport extends Transport {
    /**
     * Bind two SimulatedTransports together so they deliver to each other.
     *
     * @param {SimulatedTransport} a
     * @param {SimulatedTransport} b
     */
    static bind_pair(a: SimulatedTransport, b: SimulatedTransport): void;
    /**
     * @param {{
     *   latency_ms?: number,
     *   jitter_ms?: number,
     *   loss_pct?: number,
     *   clock?: function(): number,
     * }} [options]
     *
     * `clock` returns the current "now" in ms — used both to schedule
     * `deliver_at_ms` inside {@link send} and as the default for {@link tick}.
     * Defaults to `Date.now`, which is right for tests and any caller that
     * uses real wall time. Pair-bound transports should share the same clock
     * source (typically a single sim-time variable) so packets sent on one
     * side become deliverable at the matching moment on the other.
     */
    constructor({ latency_ms, jitter_ms, loss_pct, clock, random_seed }?: {
        latency_ms?: number;
        jitter_ms?: number;
        loss_pct?: number;
        clock?: () => number;
    });
    /**
     * Peer transport; null until {@link bind_pair} is called.
     * @type {SimulatedTransport|null}
     */
    peer: SimulatedTransport | null;
    /**
     * Inbound queue, sorted ascending by `deliver_at_ms`.
     * Each entry: `{ deliver_at_ms: number, bytes: Uint8Array }`.
     * @type {{deliver_at_ms: number, bytes: Uint8Array}[]}
     */
    in_queue: {
        deliver_at_ms: number;
        bytes: Uint8Array;
    }[];
    /**
     * Live-tunable simulated link conditions. Mutate these freely; values
     * take effect on the next `send`.
     */
    config: {
        latency_ms: number;
        jitter_ms: number;
        loss_pct: number;
    };
    /**
     * Clock source. Returns the current time in ms — read once per
     * {@link send} call to compute `deliver_at_ms`, and used as the default
     * for {@link tick} when no explicit `now_ms` is supplied.
     * @type {function(): number}
     */
    clock: () => number;
    /**
     * Deliver every packet whose `deliver_at_ms <= now_ms`. Call once per tick
     * (or whenever you want to advance the simulated link).
     *
     * @param {number} now_ms
     * @returns {number} packets delivered
     */
    tick(now_ms: number): number;
    /**
     * Number of packets queued for delivery but not yet released.
     * @returns {number}
     */
    queued_count(): number;
    /**
     * Number of packets dropped to simulated loss since construction.
     * @returns {number}
     */
    dropped_count(): number;
    /**
     * Schedule the next `n` outbound packets to be dropped unconditionally
     * (in addition to any loss from `config.loss_pct`). Useful for demos and
     * reproducible loss-burst tests where you want the recovery path to engage
     * on demand rather than after enough random drops.
     *
     * @param {number} n
     */
    force_drop_next(n: number): void;
    #private;
}
import { Transport } from "../Transport.js";
//# sourceMappingURL=SimulatedTransport.d.ts.map