with-trace.js
1.03 KB
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
}