/**
 * Per-messageId reassembly buffer for the chunked webhook.relay protocol.
 *
 * Platform splits the inbound webhook body into N WS frames so a 25 MiB body
 * can interleave with other concurrent traffic. The orchestrator must:
 * - Allocate a buffer on `webhook.relay.start` keyed by `messageId`.
 * - Append each `webhook.relay.chunk` in strict ascending sequence order.
 * - Enforce the 25 MiB hard ceiling (defensively; Platform also caps).
 * - On the chunk where `final=true`, return the assembled body + metadata so
 *   the WS handler can run verify+process and emit the ack.
 * - Garbage-collect buffers Platform abandoned mid-stream (e.g. the originating
 *   Platform process crashed between chunks) via a per-buffer TTL.
 *
 * Concurrency: a single orchestrator may be receiving many concurrent inbound
 * webhooks; the registry is a Map keyed by messageId so streams don't collide.
 *
 * Errors are NEVER thrown — every malformed input produces a typed `ChunkError`
 * with a non-secret-bearing diagnostic the WS handler maps to a
 * `rejected_misconfigured` ack. This keeps the WS handler inside its 5 s budget
 * and prevents a malicious sender from killing the orch process via a bad frame.
 */
/** Metadata captured on the start frame and kept for the lifetime of the stream. */
export interface RelayStartMeta {
    routingKey: string;
    deliveryId: string;
    event: string;
    action: string | null | undefined;
    signatureHeaderName: string | null | undefined;
    signatureHeader: string | null | undefined;
    clientIp: string | null | undefined;
    headers: Record<string, string>;
    totalSize: number;
    chunkCount: number;
    requestId?: string;
}
/** Outcome of a chunk apply: either still waiting, or completed with a ready body. */
export type ChunkApplyResult = {
    status: 'pending';
} | {
    status: 'completed';
    meta: RelayStartMeta;
    body: Buffer;
} | {
    status: 'error';
    reason: string;
};
/** Outcome of a start: success or rejection (e.g., duplicate messageId). */
export type StartResult = {
    status: 'started';
} | {
    status: 'error';
    reason: string;
};
/**
 * Per-messageId reassembly registry.
 *
 * Single instance per orchestrator process. Concurrent inbound webhooks share
 * the same registry but operate on separate Map entries keyed by messageId.
 */
export declare class RelayBufferRegistry {
    private readonly buffers;
    private readonly bufferTtlMs;
    constructor(options?: {
        bufferTtlMs?: number;
    });
    /** Number of in-flight reassembly buffers. Useful for metrics + tests. */
    get size(): number;
    /**
     * Begin a new reassembly stream. Allocates an entry keyed by `meta.messageId`
     * (passed through the meta object's caller — actually keyed externally below).
     *
     * Returns an error if `messageId` is already in flight (Platform sent two
     * `start` frames with the same id, indicates a sender bug or abuse).
     */
    start(messageId: string, meta: RelayStartMeta): StartResult;
    /**
     * Apply one chunk. Returns `pending` if more chunks expected, `completed`
     * with the assembled body when the final chunk closes the stream, or `error`
     * for any malformed-stream condition.
     *
     * Stream errors drop the buffer — the caller MUST ack `rejected_misconfigured`
     * and stop expecting further chunks for that messageId.
     */
    chunk(messageId: string, sequence: number, dataBase64: string, final: boolean): ChunkApplyResult;
    /**
     * Drop an in-flight buffer (TTL fired, stream errored, or assembly completed).
     * Idempotent: dropping a missing messageId is a no-op.
     */
    drop(messageId: string): void;
    /**
     * Drop every in-flight buffer. Used during graceful shutdown so abandoned
     * streams don't keep timers alive past process exit.
     */
    clear(): void;
}
//# sourceMappingURL=relay-buffer.d.ts.map