/**
 * OTLP JSON Writer
 *
 * Constructs OTLP ExportMetricsServiceRequest payloads as JSON with custom
 * timestamps and POSTs them to the OTLP HTTP endpoint. This bypasses the
 * OTel SDK (which doesn't expose timestamp control) while using the same
 * wire protocol and collector endpoint.
 *
 * Data flow:
 *   TimestampedSample[] → OTLP JSON (gauge dataPoints with timeUnixNano)
 *     → POST to :4318/v1/metrics → OTel Collector → Mimir → Grafana
 */
export type OtlpWriterConfig = {
    endpoint: string;
    headers?: Record<string, string>;
};
export type TimestampedSample = {
    metricName: string;
    description?: string;
    labels: Record<string, string>;
    value: number;
    timestampMs: number;
};
type OtlpAttribute = {
    key: string;
    value: {
        stringValue: string;
    };
};
type OtlpGaugeDataPoint = {
    timeUnixNano: string;
    asDouble: number;
    attributes: OtlpAttribute[];
};
type OtlpMetric = {
    name: string;
    description: string;
    gauge: {
        dataPoints: OtlpGaugeDataPoint[];
    };
};
type OtlpExportRequest = {
    resourceMetrics: Array<{
        resource: {
            attributes: OtlpAttribute[];
        };
        scopeMetrics: Array<{
            scope: {
                name: string;
            };
            metrics: OtlpMetric[];
        }>;
    }>;
};
export declare class OtlpJsonWriter {
    private endpoint;
    private headers;
    constructor(config: OtlpWriterConfig);
    write(samples: TimestampedSample[]): Promise<void>;
    /** Visible for testing. */
    buildPayload(samples: TimestampedSample[]): OtlpExportRequest;
}
/** Convert millisecond timestamp to nanosecond string (avoids Number overflow). */
export declare function msToNanoString(ms: number): string;
export declare function labelsToAttributes(labels: Record<string, string>): OtlpAttribute[];
export {};
