/**
 * Idempotency hooks for @beignet/core/server
 */
import { type IdempotencyMeta, type IdempotencyPort, type IdempotencyScope } from "../../idempotency/index.js";
import { type ActivityActor, type ActivityTenant } from "../../ports/index.js";
import type { HttpRequestLike, ServerHook } from "../types.js";
/**
 * Ports required by idempotency hooks.
 */
export type IdempotencyPorts = {
    idempotency: IdempotencyPort;
};
/**
 * Minimal context shape required for actor- and tenant-scoped idempotency.
 */
export type CtxWithIdempotency = {
    ports: IdempotencyPorts;
    actor?: ActivityActor;
    tenant?: ActivityTenant;
};
/**
 * Options for `createIdempotencyHooks(...)`.
 */
export interface IdempotencyHooksOptions<Ctx> {
    /**
     * Build the idempotency namespace for a contract.
     *
     * Defaults to `http.<contract name>` so HTTP reservations never collide with
     * use-case `runIdempotently(...)` namespaces.
     */
    namespace?: (args: {
        contract: {
            name: string;
        };
    }) => string;
    /**
     * Build the idempotency scope after context exists.
     *
     * Defaults to a scope derived from `meta.scope`: omitted metadata scopes by
     * `ctx.actor?.id` and also `ctx.tenant?.id` when present, `"actor"` scopes by
     * the actor only, `"global"` stays global, `"tenant"` scopes by the tenant,
     * and `"actor-tenant"` scopes by both.
     */
    scope?: (args: {
        ctx: Ctx;
        req: HttpRequestLike;
        meta: IdempotencyMeta;
    }) => IdempotencyScope;
    /**
     * Build the fingerprint input from the parsed request.
     *
     * Defaults to `{ path, query, body }`.
     */
    fingerprintInput?: (args: {
        path: unknown;
        query: unknown;
        body: unknown;
    }) => unknown;
}
/**
 * Create metadata-driven idempotency hooks.
 *
 * The hook reads `contract.metadata.idempotency` and enforces it with
 * `ctx.ports.idempotency`. In `beforeHandle` it reserves the client key after
 * request parsing and route hook identity resolution, replays completed matching
 * responses with an `idempotency-replayed: true` header, and rejects in-progress
 * or conflicting keys with the framework
 * `IdempotencyInProgress`/`IdempotencyConflict` catalog errors. After the
 * response-validation phase, it stores final route-owned 2xx framework-neutral
 * responses for replay and releases the reservation for framework-owned
 * responses, errors, non-2xx responses, and native `Response` results, which
 * are not replayable.
 *
 * Use `runIdempotently(...)` from `@beignet/core/idempotency` for non-HTTP
 * workflows such as jobs, listeners, webhooks, and schedules.
 *
 * @param options - Optional namespace, scope, and fingerprint-input builders.
 * @returns A server hook backed by `ctx.ports.idempotency`.
 */
export declare function createIdempotencyHooks<Ctx extends CtxWithIdempotency>(options?: IdempotencyHooksOptions<Ctx>): ServerHook<Ctx, IdempotencyPorts>;
//# sourceMappingURL=idempotency.d.ts.map