{"version":3,"sources":["../src/client-sdk/tracing/create-tracing-proxy.ts"],"sourcesContent":["import { type LangWatchTracer } from \"@/observability-sdk\";\nimport { SpanKind } from \"@opentelemetry/api\";\n\n// Type for decorator methods that receive span as first parameter\ntype DecoratorMethodWithSpan<T extends (...args: any[]) => any> =\n  (span: any, ...args: Parameters<T>) => ReturnType<T>;\n\n// Type for decorator class that maps original methods to span-aware versions\n// Only requires methods that are actually implemented in the decorator\ntype DecoratorClass<T> = new (target: T) => Partial<{\n    [K in keyof T]: T[K] extends (...args: any[]) => any\n      ? DecoratorMethodWithSpan<T[K]>\n      : T[K];\n  }>;\n\n/**\n * Creates a proxy that always creates spans for public methods.\n * Decorators can access the span as the first parameter to add additional attributes.\n *\n * @param target - The target to wrap\n * @param tracer - The tracer instance to use\n * @param DecoratorClass - Optional decorator class for custom logic\n * @returns A proxy that wraps the target with consistent tracing\n */\nexport function createTracingProxy<\n  T extends object,\n  D extends DecoratorClass<T> | undefined = undefined\n>(\n  target: T,\n  tracer: LangWatchTracer,\n  DecoratorClass?: D,\n): T {\n  const decorator = DecoratorClass ? new DecoratorClass(target) : null;\n\n  return new Proxy(target, {\n    get(target, prop, receiver) {\n      const value = Reflect.get(target, prop, receiver);\n\n      // If it's not a function, return as-is\n      if (typeof value !== \"function\") {\n        return value;\n      }\n\n      // Only trace public methods\n      if (\n        typeof prop === \"string\" &&\n        !prop.startsWith(\"_\") && // Skip private methods\n        !isGetterOrSetter(target, prop) && // Skip actual getters/setters\n        !isBuiltInMethod(prop) // Skip built-in methods\n      ) {\n        return (...args: any[]) => {\n          const spanName = `${target.constructor.name}.${prop}`;\n\n          return tracer.withActiveSpan(spanName, {\n            kind: SpanKind.CLIENT,\n            attributes: {\n              'code.function': prop,\n              'code.namespace': target.constructor.name,\n            },\n          }, (span) => {\n            // If decorator has this method, call it with span as first parameter\n            if (decorator && prop in decorator) {\n              const decoratorMethod = decorator[prop as keyof typeof decorator];\n              if (typeof decoratorMethod === \"function\") {\n                return decoratorMethod.apply(decorator, [span, ...args]);\n              }\n            }\n\n            // Default: just call the original method\n            return value.apply(target, args);\n          });\n        };\n      }\n\n      return typeof value === \"function\" ? value.bind(target) : value;\n    },\n  });\n}\n\n// Helper function to check if a property is a getter or setter\nconst isGetterOrSetter = (target: any, prop: string | symbol): boolean => {\n  // First check own properties\n  let descriptor = Object.getOwnPropertyDescriptor(target, prop);\n\n  // If not found on own properties, check prototype chain\n  if (!descriptor) {\n    const prototype = Object.getPrototypeOf(target);\n    if (prototype) {\n      descriptor = Object.getOwnPropertyDescriptor(prototype, prop);\n    }\n  }\n\n  // Return true if it's a getter or setter\n  return !!(descriptor?.get ?? descriptor?.set);\n};\n\n// Helper function to check if a method is a built-in method that should not be traced\nconst isBuiltInMethod = (prop: string | symbol): boolean => {\n  if (typeof prop !== \"string\") {\n    return false;\n  }\n\n  // List of built-in methods that should not be traced\n  const builtInMethods = [\n    'toString',\n    'valueOf',\n    'toJSON',\n    'toLocaleString',\n    'hasOwnProperty',\n    'isPrototypeOf',\n    'propertyIsEnumerable',\n    'constructor'\n  ];\n\n  return builtInMethods.includes(prop);\n};\n"],"mappings":";AACA,SAAS,gBAAgB;AAuBlB,SAAS,mBAId,QACA,QACA,gBACG;AACH,QAAM,YAAY,iBAAiB,IAAI,eAAe,MAAM,IAAI;AAEhE,SAAO,IAAI,MAAM,QAAQ;AAAA,IACvB,IAAIA,SAAQ,MAAM,UAAU;AAC1B,YAAM,QAAQ,QAAQ,IAAIA,SAAQ,MAAM,QAAQ;AAGhD,UAAI,OAAO,UAAU,YAAY;AAC/B,eAAO;AAAA,MACT;AAGA,UACE,OAAO,SAAS,YAChB,CAAC,KAAK,WAAW,GAAG;AAAA,MACpB,CAAC,iBAAiBA,SAAQ,IAAI;AAAA,MAC9B,CAAC,gBAAgB,IAAI,GACrB;AACA,eAAO,IAAI,SAAgB;AACzB,gBAAM,WAAW,GAAGA,QAAO,YAAY,IAAI,IAAI,IAAI;AAEnD,iBAAO,OAAO,eAAe,UAAU;AAAA,YACrC,MAAM,SAAS;AAAA,YACf,YAAY;AAAA,cACV,iBAAiB;AAAA,cACjB,kBAAkBA,QAAO,YAAY;AAAA,YACvC;AAAA,UACF,GAAG,CAAC,SAAS;AAEX,gBAAI,aAAa,QAAQ,WAAW;AAClC,oBAAM,kBAAkB,UAAU,IAA8B;AAChE,kBAAI,OAAO,oBAAoB,YAAY;AACzC,uBAAO,gBAAgB,MAAM,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC;AAAA,cACzD;AAAA,YACF;AAGA,mBAAO,MAAM,MAAMA,SAAQ,IAAI;AAAA,UACjC,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO,OAAO,UAAU,aAAa,MAAM,KAAKA,OAAM,IAAI;AAAA,IAC5D;AAAA,EACF,CAAC;AACH;AAGA,IAAM,mBAAmB,CAAC,QAAa,SAAmC;AAhF1E;AAkFE,MAAI,aAAa,OAAO,yBAAyB,QAAQ,IAAI;AAG7D,MAAI,CAAC,YAAY;AACf,UAAM,YAAY,OAAO,eAAe,MAAM;AAC9C,QAAI,WAAW;AACb,mBAAa,OAAO,yBAAyB,WAAW,IAAI;AAAA,IAC9D;AAAA,EACF;AAGA,SAAO,CAAC,GAAE,8CAAY,QAAZ,YAAmB,yCAAY;AAC3C;AAGA,IAAM,kBAAkB,CAAC,SAAmC;AAC1D,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO;AAAA,EACT;AAGA,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,eAAe,SAAS,IAAI;AACrC;","names":["target"]}