/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
const fallbackPerformance = {
    clearMarks: () => undefined,
    clearMeasures: () => undefined,
    getEntriesByName: () => [],
    mark: () => undefined,
    measure: () => undefined,
};
function getPerformance() {
    var _a;
    if (typeof window !== 'undefined') {
        return window.performance;
    }
    return (_a = globalThis.performance) !== null && _a !== void 0 ? _a : fallbackPerformance;
}
/**
 * A meter for measuring timings. Measurements are stored using the browser's
 * performance APIs, which provide high-resolution timestamps, as well as
 * provides visibility in the browser's developer tooling.
 */
export class TimingMeter {
    constructor(name, perf = getPerformance()) {
        this.name = name;
        this.perf = perf;
        this.measures = new Set();
        this.nextId = 0;
    }
    /**
     * Clears any measurements from the buffer.
     */
    clearMeasurements() {
        this.perf.clearMeasures(this.name);
    }
    measure(target) {
        if (target instanceof Promise) {
            const mark = this.begin();
            return target.finally(() => this.end(mark));
        }
        else if (typeof target === 'function') {
            const mark = this.begin();
            const result = target();
            this.end(mark);
            return result;
        }
        else {
            throw new Error('Input must be a function or Promise');
        }
    }
    /**
     * Returns a list of measurements that have been recorded, and clears the
     * internal measurement buffer.
     */
    takeMeasurements() {
        const timings = this.perf.getEntriesByName(this.name);
        this.clearMeasurements();
        return timings;
    }
    /**
     * Returns the last measurement to have been recorded, and clears the internal
     * measurement buffer.
     */
    takeLastMeasurement() {
        const measurements = this.takeMeasurements();
        return measurements[measurements.length - 1];
    }
    begin() {
        const mark = `${this.name}-${this.nextId++}`;
        this.measures.add(mark);
        this.perf.mark(mark);
        return mark;
    }
    end(mark) {
        this.perf.measure(this.name, mark);
        this.perf.clearMarks(mark);
        this.measures.delete(mark);
    }
}
export const paintTime = new TimingMeter('paint_time');
//# sourceMappingURL=meters.js.map
