/** * OpenTelemetry API loader with no-op fallback. * * Attempts to load `@opentelemetry/api` at runtime. When the package is not * installed, returns lightweight no-op implementations that match the subset * of the OpenTelemetry API that Weft uses. This ensures zero overhead when no SDK is * configured—every method call is a no-op that the JIT can inline away. * * @module no-op-telemetry */ type SpanAttributes = Record; export type SpanContext = { traceId: string; spanId: string; traceFlags: number; }; /** A link to another span, used to express causal relationships without parent-child hierarchy. */ export type SpanLink = { context: SpanContext; attributes?: SpanAttributes; }; type SpanStatus = { code: number; message?: string; }; /** * Minimal span interface matching the OpenTelemetry API surface we use. * * @example * ```ts * import { getOpenTelemetryApi, type OpenTelemetrySpan } from '@lostgradient/weft/observability'; * * const api = getOpenTelemetryApi(); * const tracer = api.trace.getTracer('example'); * const span: OpenTelemetrySpan = tracer.startSpan('my-operation'); * span.setAttribute('user.id', 'u-123'); * span.setStatus({ code: api.SpanStatusCode.OK }); * span.end(); * ``` */ export type OpenTelemetrySpan = { setAttribute(key: string, value: string | number | boolean): void; setStatus(status: SpanStatus): void; recordException(exception: Error | string): void; end(endTime?: number): void; spanContext(): SpanContext; }; type SpanOptions = { attributes?: SpanAttributes; startTime?: number; links?: SpanLink[]; }; /** * Minimal tracer interface. * * @example * ```ts * import { getOpenTelemetryApi, type OpenTelemetryTracer } from '@lostgradient/weft/observability'; * * const api = getOpenTelemetryApi(); * const tracer: OpenTelemetryTracer = api.trace.getTracer('my-service', '1.0.0'); * const span = tracer.startSpan('task', { attributes: { 'task.id': '42' } }); * span.end(); * ``` */ export type OpenTelemetryTracer = { startSpan(name: string, options?: SpanOptions, context?: unknown): OpenTelemetrySpan; }; type InstrumentOptions = { unit?: string; description?: string; }; type OpenTelemetryHistogram = { record(value: number, attributes?: SpanAttributes): void; }; type OpenTelemetryCounter = { add(value: number, attributes?: SpanAttributes): void; }; type OpenTelemetryUpDownCounter = { add(value: number, attributes?: SpanAttributes): void; }; /** * Minimal meter interface. * * @example * ```ts * import { getOpenTelemetryApi, type OpenTelemetryMeter } from '@lostgradient/weft/observability'; * * const api = getOpenTelemetryApi(); * const meter: OpenTelemetryMeter = api.metrics.getMeter('my-service'); * const counter = meter.createCounter('requests.total'); * counter.add(1, { route: '/api/start' }); * ``` */ export type OpenTelemetryMeter = { createHistogram(name: string, options?: InstrumentOptions): OpenTelemetryHistogram; createCounter(name: string, options?: InstrumentOptions): OpenTelemetryCounter; createUpDownCounter(name: string, options?: InstrumentOptions): OpenTelemetryUpDownCounter; }; /** * The resolved OpenTelemetry API surface Weft consumes. * * @example * ```ts * import { getOpenTelemetryApi, type OpenTelemetryApi } from '@lostgradient/weft/observability'; * * const api: OpenTelemetryApi = getOpenTelemetryApi(); * const tracer = api.trace.getTracer('my-app'); * const span = tracer.startSpan('boot'); * span.setStatus({ code: api.SpanStatusCode.OK }); * span.end(); * ``` */ export type OpenTelemetryApi = { trace: { getTracer(name: string, version?: string): OpenTelemetryTracer; setSpan(context: unknown, span: OpenTelemetrySpan): unknown; }; metrics: { getMeter(name: string, version?: string): OpenTelemetryMeter; }; context: { ROOT_CONTEXT: unknown; with(ctx: unknown, fn: () => T): T; }; SpanStatusCode: { OK: number; ERROR: number; UNSET: number; }; }; /** Shared no-op span methods for lightweight span adapters that only need a custom spanContext. */ export declare const NO_OP_SPAN_METHODS: { readonly setAttribute: (key: string, value: string | number | boolean) => void; readonly setStatus: (status: SpanStatus) => void; readonly recordException: (exception: string | Error) => void; readonly end: (endTime?: number | undefined) => void; }; /** Reset the cached API between tests so specific loader branches can be exercised deterministically. */ export declare function resetCachedOpenTelemetryApiForTesting(): void; /** Check whether a loaded module exposes the subset of the OpenTelemetry API Weft requires. */ export declare function isSupportedOpenTelemetryApi(value: Partial | undefined): value is OpenTelemetryApi; /** * Resolve the installed OpenTelemetry API using an injectable loader. * Returns `undefined` when the module is unavailable or exposes the wrong shape. */ export declare function resolveInstalledOpenTelemetryApi(loader?: (moduleName: string) => unknown): OpenTelemetryApi | undefined; /** * Returns the `@opentelemetry/api` module if installed, otherwise returns * no-op implementations. The result is cached after the first call. * * This function is the single entry point for all OpenTelemetry interactions in Weft. * When no SDK is configured the no-op implementations ensure zero overhead * because every method is an empty function the JIT can inline away. * * @example * ```ts * import { getOpenTelemetryApi } from '@lostgradient/weft/observability'; * * // Works whether the OpenTelemetry API package is installed or not * const api = getOpenTelemetryApi(); * const tracer = api.trace.getTracer('my-app'); * const span = tracer.startSpan('startup'); * span.end(); * ``` */ export declare function getOpenTelemetryApi(loader?: (moduleName: string) => unknown): OpenTelemetryApi; export {};