feat(core-shared/instrumentation): withSpan returns Instrumented<F>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { describe, it, expect, vi } from "vitest";
|
import { describe, it, expect, expectTypeOf, vi } from "vitest";
|
||||||
import { withSpan } from "@/instrumentation/with-span";
|
import { withSpan } from "@/instrumentation/with-span";
|
||||||
import type { ITracer, ISpan, SpanOpts } from "@/instrumentation/tracer.interface";
|
import type { ITracer, ISpan, SpanOpts } from "@/instrumentation/tracer.interface";
|
||||||
|
import type { Instrumented } from "@/conformance/brands";
|
||||||
|
|
||||||
function makeRecordingTracer() {
|
function makeRecordingTracer() {
|
||||||
const calls: SpanOpts[] = [];
|
const calls: SpanOpts[] = [];
|
||||||
@@ -60,3 +61,12 @@ describe("withSpan", () => {
|
|||||||
expect(calls.every((c) => c.name === "test.same")).toBe(true);
|
expect(calls.every((c) => c.name === "test.same")).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("withSpan — brand", () => {
|
||||||
|
it("returns an Instrumented<F>", () => {
|
||||||
|
const { tracer } = makeRecordingTracer();
|
||||||
|
const fn = async (a: number) => a + 1;
|
||||||
|
const wrapped = withSpan(tracer, { name: "test.brand", op: "use-case" }, fn);
|
||||||
|
expectTypeOf(wrapped).toMatchTypeOf<Instrumented<typeof fn>>();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
import type { ITracer, SpanOpts } from "./tracer.interface";
|
import type { ITracer, SpanOpts } from "./tracer.interface";
|
||||||
|
import type { Instrumented } from "../conformance/brands";
|
||||||
|
|
||||||
export function withSpan<Args extends unknown[], R>(
|
export function withSpan<Args extends unknown[], R>(
|
||||||
tracer: ITracer,
|
tracer: ITracer,
|
||||||
opts: SpanOpts | ((args: Args) => SpanOpts),
|
opts: SpanOpts | ((args: Args) => SpanOpts),
|
||||||
fn: (...args: Args) => Promise<R>,
|
fn: (...args: Args) => Promise<R>,
|
||||||
): (...args: Args) => Promise<R> {
|
): Instrumented<(...args: Args) => Promise<R>> {
|
||||||
return (...args) => {
|
const wrapped: (...args: Args) => Promise<R> = (...args) => {
|
||||||
const resolved = typeof opts === "function" ? opts(args) : opts;
|
const resolved = typeof opts === "function" ? opts(args) : opts;
|
||||||
return tracer.startSpan(resolved, () => fn(...args));
|
return tracer.startSpan(resolved, () => fn(...args));
|
||||||
};
|
};
|
||||||
|
// Cast is the only runtime concession — the brand is a phantom type;
|
||||||
|
// there is no real `__instrumented` property at runtime.
|
||||||
|
return wrapped as Instrumented<(...args: Args) => Promise<R>>;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user