import type { MetricsClient } from "../../clients/metricsClient";
import type { OperationalMetric } from "../../generated-proto/pb_schema/camera_kit/v3/operational_metrics";
import type { JoinMetricNames, MetricDimensions } from "./Metric";
import { Metric } from "./Metric";
interface Measure {
    name: string;
    duration: number;
    dimensions: MetricDimensions;
}
/** @internal */
export type LatencyMetric = OperationalMetric & {
    metric: Extract<OperationalMetric["metric"], {
        $case: "latencyMillis";
    }>;
};
/** @internal */
export declare class Timer<Name extends string> extends Metric {
    readonly name: Name;
    private readonly marks;
    private readonly measures;
    private readonly startTime;
    private stopped;
    constructor(name: Name, dimensions?: MetricDimensions);
    /**
     * Return all measures created by this Timer and any child timers.
     */
    getMeasures(): ReadonlyArray<Measure>;
    /**
     * Create a child Timer, using this Timer's name as a prefix when naming the new Timer. Any measures made with the
     * child Timer will be included when calling `getMeasures()` on this Timer, or when calling `toOperationalMetric`
     * on this Timer.
     *
     * @example
     * ```ts
     * const parent = new Timer('parent')
     * const child = parent.mark('child') // child metric name is parent_child.
     *
     * child.measure()
     * const measures = parent.getMeasures() // has one element.
     * ```
     *
     * @param name
     * @param dimensions If omitted, the child timer will NOT inherit dimensions from the parent -- if the child timer
     * should re-use the parent's dimensions, this must be done explicitly by passing the parent's dimensions as an
     * argument here.
     * @returns A child Timer.
     */
    mark<MarkName extends string>(name: MarkName, dimensions?: MetricDimensions): Timer<JoinMetricNames<Name, MarkName>>;
    /**
     * Measure the time (in milliseconds) since this Timer was created.
     *
     * If a name is provided, the measure's name will be prefixed with the name of this Timer. Otherwise the name of
     * the measure will be the name of this Timer.
     *
     * @example
     * ```ts
     * const timer = new Timer('a')
     * timer.measure('b')
     * const measures = timer.getMeasures()
     * // measure[0].name === 'a_b'
     * ```
     *
     * @param name
     * @returns
     */
    measure(): Measure | undefined;
    measure(dimensions: MetricDimensions): Measure | undefined;
    measure(name: string): Measure | undefined;
    measure(name: string, dimensions: MetricDimensions): Measure | undefined;
    /**
     * Remove all measures from this Timer and any child timers previously created by calls to `mark()`.
     */
    clear(): void;
    /**
     * Prevent any future measures from being created by this Timer or any child timers.
     */
    stop(): void;
    /**
     * Report this metric using {@link MetricsClient}.
     *
     * After reporting, the Timer can longer be used. Its internal state is cleared and cannot be updated. Calling this
     * method a second time will no-op.
     *
     * @param reporter All measurements will be reported using the given reporter.
     */
    stopAndReport(client: MetricsClient): Promise<void>;
    /**
     * Convert all measures from this Timer and from any child timers into an array of {@link OperationalMetric}
     * objects, which can be sent to the backend.
     *
     * @returns
     */
    toOperationalMetric(): LatencyMetric[];
}
export {};
//# sourceMappingURL=Timer.d.ts.map