import { type KvPair } from './moqt.js';
/**
 * MoQ → QUIC object mapping. Values are the on-the-wire identifiers used by the
 * low-level protocol (see MOQ_MAPPING_* in ./moqt.ts) and must stay in sync.
 */
export declare enum MoqMapping {
    ObjectPerDatagram = "ObjPerDatagram",
    SubgroupPerGroup = "SubGroupPerObj"
}
export type ObjStatus = 'queued' | 'sent' | 'aborted' | 'dropped';
export interface ObjInfo {
    objId: number;
    groupId: number;
    status: ObjStatus;
}
/** Options for starting a new group, passed to `Track.sendObject`. */
export interface NewGroupOptions {
    priority: number;
}
export interface TrackInfo {
    namespace: string[];
    name: string;
    trackAlias: number;
    moqMapping: MoqMapping;
    numSubscribers: number;
    numInFlight: number;
    currentGroup: number;
    currentObject: number;
}
export interface MoqInitOptions {
    serverCertificateHash?: Uint8Array | null;
    alpnVersion?: string;
}
/**
 * Called for every object received on a subscription. It is handed the raw
 * payload reader (a `ReadableStream` positioned at the object payload), the
 * object extension headers, and the payload length (`undefined` means "read to
 * the end of the datagram"). It returns whether this was the last object
 * (end of stream). Media decoding lives in the caller, keeping `Moq` media-free.
 */
export type ObjectCallback = (reader: ReadableStream<Uint8Array>, extensionHeaders: KvPair[], length?: number) => Promise<boolean> | boolean;
export interface SubscriptionInfo {
    namespace: string[];
    name: string;
    subscribeRequestId: number;
    trackAlias: number;
}
/**
 * Keep-alive loop options. When passed to `Moq.setup`, the session periodically
 * sends a keep-alive PUBLISH while idle (no object sent within `everyMs`).
 * `namespace`/`name` default to 'keepAlive' and a random name.
 */
export interface KeepAliveOptions {
    everyMs: number;
    namespace?: string;
    name?: string;
}
interface Subscriber {
    subscriptionRequestId: number;
    forward: number;
    parameters: KvPair[];
}
/**
 * Handle for one object handed to `Track.sendObject`. Lets the caller observe
 * delivery (`getInfo`) and cancel an object that has not been written yet
 * (`abort`).
 */
export declare class ObjData {
    groupId: number;
    objId: number;
    status: ObjStatus;
    readonly priority: number;
    readonly data: BufferSource | undefined;
    readonly newGroup: boolean;
    readonly extensionHeaders: KvPair[];
    readonly callback?: (obj: ObjData) => void;
    private track;
    constructor(track: Track, groupId: number, objId: number, status: ObjStatus, priority: number, data?: BufferSource, newGroup?: boolean, extensionHeaders?: KvPair[], callback?: (obj: ObjData) => void);
    /** Synchronous snapshot: object id, group id and current status. */
    getInfo(): ObjInfo;
    /** Drop this object from the queue if it has not been written yet. */
    abort(): void;
}
/**
 * A published track. Created via `Moq.addTrack`. Carries the per-track send
 * queue, group/object sequencing, open subgroup stream, and subscriber list.
 */
export declare class Track {
    readonly namespace: string[];
    readonly name: string;
    readonly trackAlias: number;
    readonly publisherRequestId: number;
    readonly authInfo: string | undefined;
    readonly maxInFlightRequests: number;
    readonly moqMapping: MoqMapping;
    subscribers: Subscriber[];
    private moq;
    private queue;
    private draining;
    private closed;
    private forwarding;
    private resumeNeedsNewGroup;
    private firstObjectSent;
    private currentGroupSeq;
    private currentObjectSeq;
    private currentGroupPriority;
    private streams;
    private groupLastObj;
    constructor(moq: Moq, namespace: string[], name: string, trackAlias: number, publisherRequestId: number, maxInFlightRequests: number, authInfo: string | undefined, moqMapping: MoqMapping);
    /**
     * Queue an object for delivery. Passing `newGroupOptions` starts a new group
     * (e.g. a video keyframe) with the given publisher priority; omit it to append
     * to the current group. `extensionHeaders` are MoQ object extension headers
     * (e.g. MoQMI media metadata). `callback` fires once the object is written.
     *
     * Returns an `ObjData` handle. Objects are dropped (status `dropped`) when the
     * subscription is not being forwarded (Forward State 0 / no subscriber), or
     * when the pending queue is already at `maxInFlightRequests`.
     */
    sendObject(data: BufferSource | undefined, newGroupOptions?: NewGroupOptions, extensionHeaders?: KvPair[], callback?: (obj: ObjData) => void): ObjData;
    /** Snapshot of the track's identity and live counters. */
    getInfo(): TrackInfo;
    /** Stop the track: drop the queue, close streams, send PUBLISH_DONE. */
    close(): Promise<void>;
    isForwarding(): boolean;
    _setForwarding(forwarding: boolean): void;
    private resetStreams;
    _addSubscriber(subscriptionRequestId: number, forward: number, parameters: KvPair[]): void;
    _removeSubscribersByRequestId(requestId: number): Subscriber[];
    _lastSent(): {
        group: number | undefined;
        obj: number | undefined;
    };
    _abort(obj: ObjData): void;
    private advanceSequence;
    private drain;
    private writeObject;
}
/**
 * A subscribed track. Created via `Moq.subscribe`. Holds the subscription
 * identity and the per-object callback the receive loops invoke (routed by
 * track alias). Symmetric to `Track` on the publisher side.
 */
export declare class Subscription {
    readonly namespace: string[];
    readonly name: string;
    readonly subscribeRequestId: number;
    readonly trackAlias: number;
    readonly authInfo: string | undefined;
    private moq;
    private onObject;
    private closed;
    constructor(moq: Moq, namespace: string[], name: string, subscribeRequestId: number, trackAlias: number, authInfo: string | undefined, onObject: ObjectCallback);
    /** Snapshot of the subscription's identity. */
    getInfo(): SubscriptionInfo;
    /** Stop the subscription (best-effort UNSUBSCRIBE). */
    unsubscribe(): Promise<void>;
    _deliver(reader: ReadableStream<Uint8Array>, extensionHeaders: KvPair[], length?: number): Promise<boolean>;
}
export declare enum MoqState {
    Idle = 0,// before init()
    Connecting = 1,// init() called; transport + control stream coming up
    Running = 2,// SETUP handshake done; control loop active
    Closed = 3
}
/**
 * A MoQ publisher session over WebTransport. Owns the transport, the control
 * stream, the inbound control loop (subscriptions), and the set of tracks.
 */
export declare class Moq {
    private moqt;
    private connecting;
    private _state;
    get state(): MoqState;
    private tracks;
    private nextClientReqId;
    private nextAliasValue;
    private keepAliveOpts;
    private keepAliveInterval;
    private lastObjectSentMs;
    private pendingPublish;
    private subscriptions;
    private subscriptionsByAlias;
    private receiveLoopsStarted;
    private pendingSubscribe;
    /**
     * Open the transport (sync). Connection + control stream creation happen in
     * the background; `setup` and `addTrack` await readiness.
     */
    init(urlHostPort: string, options?: MoqInitOptions): void;
    /** Perform the MoQ SETUP handshake and start the control loop. */
    setup(keepAliveOpts?: KeepAliveOptions): Promise<void>;
    /** Publish a track (sends PUBLISH, resolves on PUBLISH_OK). */
    addTrack(namespace: string[], name: string, maxInFlightRequests: number, authInfo: string | undefined, moqMapping: MoqMapping): Promise<Track>;
    /**
     * Subscribe to a track (sends SUBSCRIBE, resolves on SUBSCRIBE_OK). Objects
     * received for the track are routed to `onObject` by the negotiated track
     * alias. A SUBSCRIBE_ERROR is retried after `SLEEP_SUBSCRIBE_ERROR_MS`.
     */
    subscribe(namespace: string[], name: string, authInfo: string | undefined, onObject: ObjectCallback): Promise<Subscription>;
    /** Drop queues, close tracks/subscriptions and the transport (best-effort, async teardown). */
    close(): void;
    private startKeepAlive;
    private stopKeepAlive;
    private maybeSendKeepAlive;
    _wt(): any;
    _controlWriter(): WritableStream<Uint8Array>;
    _markObjectSent(): void;
    private runControlLoop;
    private resolvePublish;
    private resolveSubscribe;
    private rejectByRequestId;
    private onSubscribe;
    private onRequestUpdate;
    private onUnsubscribe;
    private ensureReceiveLoops;
    private runStreamReceiveLoop;
    private receiveSubgroupStream;
    private runDatagramReceiveLoop;
    private controlWriter;
    private controlReader;
    private trackByFullName;
    private trackByPublisherRequestId;
    private allocateClientReqId;
    private allocateTrackAlias;
}
export {};
//# sourceMappingURL=moq.d.ts.map