import { type Attributes, type Span, type SpanKind } from "@opentelemetry/api";
import type { FpxLogger } from "./logger.js";
export type MeasureOptions<
/**
 * Arguments for the function being measured
 */
ARGS, 
/**
 * The return type of the function being measured. This could be a value including a promise or a(n) (async) generator
 */
RESULT> = {
    name: string;
    /**
     * The kind of the span
     */
    spanKind?: SpanKind;
    /**
     * Attributes to be added to the span
     */
    attributes?: Attributes;
    onStart?: (span: Span, args: ARGS) => void;
    /**
     * Allows you to specify a function that will be called when the span ends
     * and will be passed the span & result of the function being measured.
     *
     * This way you can do things like add additional attributes to the span
     */
    onSuccess?: (span: Span, result: ExtractInnerResult<RESULT>) => RESULT extends Promise<unknown> ? Promise<void> | void : void;
    /**
     * This is an advanced feature in cases where you don't want the open telemetry spans
     * to be ended automatically.
     *
     * Some disclaimers: this can only be used in combination with promises and with an onSuccess
     *  handler. This handler should call span.end() at some point. If you want the on success
     * handler to trigger another async function you may want to use waitUntil to prevent the
     * worker from terminating before the traces/spans are finished & send to the server
     *
     * How this is currently used;:
     * We're using it to show the duration of a request in case it's being streamed back to
     * the client. In those cases the response is returned early while work is still being done.
     *
     */
    endSpanManually?: boolean;
    /**
     * Allows you to specify a function that will be called when the span ends
     * with an error and will be passed the (current) span & error that occurred.
     *
     * This way you can do things like add additional attributes to the span
     */
    onError?: (span: Span, error: unknown) => void;
    /**
     * You can specify a function that will allow you to throw an error based on the value of the
     * result (returned by the measured function). This error will only be used for recording the error
     * in the span and will not be thrown.
     */
    checkResult?: (result: ExtractInnerResult<RESULT>) => RESULT extends Promise<unknown> ? Promise<void> | void : RESULT extends AsyncGenerator<unknown, unknown, unknown> ? Promise<void> | void : void;
    /**
     * Optional logger module to use for logging on errors, etc.
     * Similar to passing `console`. Should be an object with methods `debug`, `info`, `warn`, `error`.
     */
    logger?: FpxLogger;
};
type ExtractInnerResult<TYPE> = TYPE extends Generator<infer T, infer TReturn, unknown> ? T | TReturn : TYPE extends AsyncGenerator<infer T, infer TReturn, unknown> ? T | TReturn : TYPE extends Promise<infer R> ? R : TYPE;
/**
 * Wraps a function in a span, measuring the time it takes to execute
 * the function.
 *
 * @param name (string) The name of the span that will be created
 * @param fn (function) The function to be measured
 * @returns (function) The wrapped function, with the same signature as the original function
 */
export declare function measure<T, A extends unknown[]>(name: string, fn: (...args: A) => T): (...args: A) => T;
/**
 * Wraps a function in a span, measuring the time it takes to execute
 * the function.
 *
 * @param options param name and spanKind
 * @param fn
 */
export declare function measure<ARGS extends unknown[], RESULT>(options: MeasureOptions<ARGS, RESULT>, fn: (...args: ARGS) => RESULT): (...args: ARGS) => RESULT;
export declare function isGeneratorValue<T = unknown, TReturn = unknown, TNext = unknown>(value: unknown): value is Generator<T, TReturn, TNext>;
/**
 * Type guard to check if a function is an async generator.
 *
 * @param fn - The function to be checked
 * @returns true if the function is an async generator, otherwise false
 */
export declare function isAsyncGeneratorValue<T = unknown, TReturn = unknown, TNext = unknown>(value: unknown): value is AsyncGenerator<T, TReturn, TNext>;
export {};
