import { createRequestContext } from './context.js' /** * 判断一个值是否已是 RequestContext(鸭子类型:有 string traceId 与 child 方法)。 * @param {any} v * @returns {boolean} */ function isRequestContext(v) { return ( !!v && typeof v === 'object' && typeof v.traceId === 'string' && typeof v.child === 'function' ) } /** * 把「`(ctx, ...args) => ...`」的函数包成自动注入 ctx 的函数。 * 调用时若首参不是 `RequestContext`,则 `createRequestContext()` 注入为首参(自动生成 traceId); * 已传则透传同一 ctx(同一 trace)。 * * @template {(...args: any[]) => any} F * @param {F} fn * @returns {F} */ export function withTrace(fn) { /** @type {any} */ const wrapped = function (/** @type {any[]} */ ...args) { // @ts-ignore — 透传调用方 this,保留任意可调用形态。 if (isRequestContext(args[0])) return fn.apply(this, args) // @ts-ignore return fn.apply(this, [createRequestContext(), ...args]) } return wrapped }