Repository: vercel/next.js
File: packages/next/src/server/lib/trace/tracer.ts (TypeScript)

Code before:

  public getActiveScopeSpan(): Span | undefined {
    return trace.getSpan(context?.active())
  }

  public withPropagatedContext<T, C>(
    carrier: C,
    fn: () => T,
    getter?: TextMapGetter<C>,
    force = false
  ): T {
    const activeContext = context.active()
    if (!force && trace.getSpanContext(activeContext)) {
      // Active span is already set, too late to propagate.
      return fn()
    }
    const extractionContext = force ? ROOT_CONTEXT : activeContext
    const remoteContext = propagation.extract(
      extractionContext,
      carrier,
      getter
    )

    if (force && !trace.getSpanContext(remoteContext)) {
      // If nothing was extracted, preserve the existing active context.
      return fn()
    }

    return context.with(remoteContext, fn)
  }

  // Trace, wrap implementation is inspired by datadog trace implementation
  // (https://datadoghq.dev/dd-trace-js/interfaces/tracer.html#trace).
  public trace<T>(
    type: SpanTypes,
    fn: (span?: Span, done?: (error?: Error) => any) => Promise<T>
  ): Promise<T>
  public trace<T>(
    type: SpanTypes,
    fn: (span?: Span, done?: (error?: Error) => any) => T
  ): T
  public trace<T>(
    type: SpanTypes,
    options: TracerSpanOptions,
    fn: (span?: Span, done?: (error?: Error) => any) => Promise<T>
  ): Promise<T>
  public trace<T>(
    type: SpanTypes,
    options: TracerSpanOptions,
    fn: (span?: Span, done?: (error?: Error) => any) => T
  ): T

Review comment (refactor):
We'll potentially lose useful otel baggage attached to `remoteContext` even if it has no spans. In the `force` case, should we still call `context.with`? eg:

```ts

if (force) {
  const fromRoot = propagation.extract(ROOT_CONTEXT, carrier, getter);

  // If remote span exists, use it as parent
  if (trace.getSpanContext(fromRoot)) {
    return context.with(fromRoot, fn);
  }

  // Otherwise, preserve active local span, but still merge baggage.
  const merged = propagation.extract(context.active(), carrier, getter);
  return context.with(merged, fn);
}
```


Code after:

  public getActiveScopeSpan(): Span | undefined {
    return trace.getSpan(context?.active())
  }

  public withPropagatedContext<T, C>(
    carrier: C,
    fn: () => T,
    getter?: TextMapGetter<C>,
    force = false
  ): T {
    const activeContext = context.active()

    if (force) {
      const remoteContext = propagation.extract(ROOT_CONTEXT, carrier, getter)

      if (trace.getSpanContext(remoteContext)) {
        return context.with(remoteContext, fn)
      }

      // Preserve the current active span while still merging any extracted
      // baggage/context values from the carrier.
      const mergedContext = propagation.extract(activeContext, carrier, getter)
      return context.with(mergedContext, fn)
    }

    if (trace.getSpanContext(activeContext)) {
      // Active span is already set, too late to propagate.
      return fn()
    }

    const remoteContext = propagation.extract(activeContext, carrier, getter)
    return context.with(remoteContext, fn)
  }

  // Trace, wrap implementation is inspired by datadog trace implementation
  // (https://datadoghq.dev/dd-trace-js/interfaces/tracer.html#trace).
  public trace<T>(
    type: SpanTypes,
    fn: (span?: Span, done?: (error?: Error) => any) => Promise<T>
  ): Promise<T>
  public trace<T>(
    type: SpanTypes,
    fn: (span?: Span, done?: (error?: Error) => any) => T
  ): T
  public trace<T>(
    type: SpanTypes,
    options: TracerSpanOptions,
    fn: (span?: Span, done?: (error?: Error) => any) => Promise<T>
  ): Promise<T>
  public trace<T>(