Files
agentic-dev/packages/core-shared/src/instrumentation/with-span.ts

29 lines
1.2 KiB
TypeScript

import type { ITracer, SpanOpts } from "./tracer.interface";
import type { Instrumented } from "../conformance/brands";
import { attachBrand } from "../conformance/brand-runtime";
export function withSpan<Args extends unknown[], R, Extra extends object>(
tracer: ITracer,
opts: SpanOpts | ((args: Args) => SpanOpts),
fn: ((...args: Args) => Promise<R>) & Extra,
): Instrumented<((...args: Args) => Promise<R>) & Extra>;
export function withSpan<Args extends unknown[], R>(
tracer: ITracer,
opts: SpanOpts | ((args: Args) => SpanOpts),
fn: (...args: Args) => Promise<R>,
): Instrumented<(...args: Args) => Promise<R>>;
export function withSpan<Args extends unknown[], R>(
tracer: ITracer,
opts: SpanOpts | ((args: Args) => SpanOpts),
fn: (...args: Args) => Promise<R>,
): Instrumented<(...args: Args) => Promise<R>> {
const wrapped: (...args: Args) => Promise<R> = (...args) => {
const resolved = typeof opts === "function" ? opts(args) : opts;
return tracer.startSpan(resolved, () => fn(...args));
};
attachBrand(wrapped, "__instrumented");
// Cast is the type-level concession — the brand is now also a non-enumerable
// runtime property attached above by `attachBrand`.
return wrapped as Instrumented<(...args: Args) => Promise<R>>;
}