autotel 5.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto.cjs +1 -1
- package/dist/auto.js +1 -1
- package/dist/correlation-id.cjs +9 -9
- package/dist/correlation-id.js +1 -1
- package/dist/decorators.cjs +2 -2
- package/dist/decorators.cjs.map +1 -1
- package/dist/decorators.js +1 -1
- package/dist/event.cjs +4 -4
- package/dist/event.js +1 -1
- package/dist/{functional-Bit6noRu.js → functional-BnDUxnSl.js} +2 -4
- package/dist/{functional-Bit6noRu.js.map → functional-BnDUxnSl.js.map} +1 -1
- package/dist/{functional-Cj7PSItS.cjs → functional-DcLBuCPz.cjs} +12 -14
- package/dist/{functional-Cj7PSItS.cjs.map → functional-DcLBuCPz.cjs.map} +1 -1
- package/dist/functional.cjs +1 -1
- package/dist/functional.js +1 -1
- package/dist/http.cjs +2 -2
- package/dist/http.cjs.map +1 -1
- package/dist/http.js +1 -1
- package/dist/index.cjs +23 -164
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -145
- package/dist/index.js.map +1 -1
- package/dist/init-C3RApHKJ.cjs +3371 -0
- package/dist/init-C3RApHKJ.cjs.map +1 -0
- package/dist/{init-CTyqG9qR.d.ts → init-D6n2diBy.d.ts} +21 -2
- package/dist/init-D6n2diBy.d.ts.map +1 -0
- package/dist/init-R-gSEXkJ.js +3190 -0
- package/dist/init-R-gSEXkJ.js.map +1 -0
- package/dist/{init-a4yPDYqC.d.cts → init-XzXzrarP.d.cts} +21 -2
- package/dist/init-XzXzrarP.d.cts.map +1 -0
- package/dist/instrumentation.cjs +1 -1
- package/dist/instrumentation.js +1 -1
- package/dist/messaging.cjs +1 -1
- package/dist/messaging.js +1 -1
- package/dist/semantic-helpers.cjs +1 -1
- package/dist/semantic-helpers.js +1 -1
- package/dist/webhook.cjs +1 -1
- package/dist/webhook.js +1 -1
- package/dist/workflow-distributed.cjs +1 -1
- package/dist/workflow-distributed.js +1 -1
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.js +1 -1
- package/dist/yaml-config.d.cts +1 -1
- package/dist/yaml-config.d.ts +1 -1
- package/package.json +2 -3
- package/dist/event-CwIpFdoY.cjs +0 -778
- package/dist/event-CwIpFdoY.cjs.map +0 -1
- package/dist/event-pLMF5b3d.js +0 -761
- package/dist/event-pLMF5b3d.js.map +0 -1
- package/dist/init-B2uvZReD.cjs +0 -1120
- package/dist/init-B2uvZReD.cjs.map +0 -1
- package/dist/init-CTyqG9qR.d.ts.map +0 -1
- package/dist/init-CdEWjhvl.js +0 -1043
- package/dist/init-CdEWjhvl.js.map +0 -1
- package/dist/init-a4yPDYqC.d.cts.map +0 -1
- package/dist/operation-context-CKBoA4Qy.js +0 -59
- package/dist/operation-context-CKBoA4Qy.js.map +0 -1
- package/dist/operation-context-hzKbTKnt.cjs +0 -72
- package/dist/operation-context-hzKbTKnt.cjs.map +0 -1
- package/dist/track-BBcxEJEC.js +0 -1110
- package/dist/track-BBcxEJEC.js.map +0 -1
- package/dist/track-BI6dmZ2X.cjs +0 -1207
- package/dist/track-BI6dmZ2X.cjs.map +0 -1
- package/skills/analyze-traces/SKILL.md +0 -209
- package/skills/autotel-core/SKILL.md +0 -166
- package/skills/autotel-events/SKILL.md +0 -84
- package/skills/autotel-frameworks/SKILL.md +0 -125
- package/skills/autotel-instrumentation/SKILL.md +0 -150
- package/skills/autotel-request-logging/SKILL.md +0 -99
- package/skills/autotel-structured-errors/SKILL.md +0 -125
- package/skills/build-audit-trails/SKILL.md +0 -460
- package/skills/build-audit-trails/references/audit-queries.md +0 -73
- package/skills/build-audit-trails/references/framework-wiring.md +0 -196
- package/skills/debug-missing-spans/SKILL.md +0 -250
- package/skills/migrate-to-autotel/SKILL.md +0 -269
- package/skills/review-otel-patterns/SKILL.md +0 -540
- package/skills/review-otel-patterns/references/code-review.md +0 -76
- package/skills/review-otel-patterns/references/processor-pipeline.md +0 -205
- package/skills/review-otel-patterns/references/structured-errors.md +0 -102
- package/skills/review-otel-patterns/references/wide-spans.md +0 -85
- package/skills/tune-sampling/SKILL.md +0 -290
package/dist/auto.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_rolldown_runtime = require('./rolldown-runtime-C_NdSu1c.cjs');
|
|
2
|
-
const require_init = require('./init-
|
|
2
|
+
const require_init = require('./init-C3RApHKJ.cjs');
|
|
3
3
|
const require_yaml_config = require('./yaml-config.cjs');
|
|
4
4
|
let node_module = require("node:module");
|
|
5
5
|
node_module = require_rolldown_runtime.__toESM(node_module, 1);
|
package/dist/auto.js
CHANGED
package/dist/correlation-id.cjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const
|
|
2
|
+
const require_init = require('./init-C3RApHKJ.cjs');
|
|
3
3
|
|
|
4
|
-
exports.CORRELATION_ID_BAGGAGE_KEY =
|
|
5
|
-
exports.generateCorrelationId =
|
|
6
|
-
exports.getCorrelationId =
|
|
7
|
-
exports.getCorrelationStorage =
|
|
8
|
-
exports.getOrCreateCorrelationId =
|
|
9
|
-
exports.runWithCorrelationId =
|
|
10
|
-
exports.setCorrelationId =
|
|
11
|
-
exports.setCorrelationIdInBaggage =
|
|
4
|
+
exports.CORRELATION_ID_BAGGAGE_KEY = require_init.CORRELATION_ID_BAGGAGE_KEY;
|
|
5
|
+
exports.generateCorrelationId = require_init.generateCorrelationId;
|
|
6
|
+
exports.getCorrelationId = require_init.getCorrelationId;
|
|
7
|
+
exports.getCorrelationStorage = require_init.getCorrelationStorage;
|
|
8
|
+
exports.getOrCreateCorrelationId = require_init.getOrCreateCorrelationId;
|
|
9
|
+
exports.runWithCorrelationId = require_init.runWithCorrelationId;
|
|
10
|
+
exports.setCorrelationId = require_init.setCorrelationId;
|
|
11
|
+
exports.setCorrelationIdInBaggage = require_init.setCorrelationIdInBaggage;
|
package/dist/correlation-id.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as setCorrelationId, S as runWithCorrelationId, _ as CORRELATION_ID_BAGGAGE_KEY, b as getCorrelationStorage, v as generateCorrelationId, w as setCorrelationIdInBaggage, x as getOrCreateCorrelationId, y as getCorrelationId } from "./init-R-gSEXkJ.js";
|
|
2
2
|
|
|
3
3
|
export { CORRELATION_ID_BAGGAGE_KEY, generateCorrelationId, getCorrelationId, getCorrelationStorage, getOrCreateCorrelationId, runWithCorrelationId, setCorrelationId, setCorrelationIdInBaggage };
|
package/dist/decorators.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_config = require('./config.cjs');
|
|
3
|
-
const
|
|
3
|
+
const require_init = require('./init-C3RApHKJ.cjs');
|
|
4
4
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
5
5
|
|
|
6
6
|
//#region src/decorators.ts
|
|
@@ -14,7 +14,7 @@ function Trace(nameOrOptions, maybeOptions) {
|
|
|
14
14
|
return async function(...args) {
|
|
15
15
|
return require_config.getConfig().tracer.startActiveSpan(spanName, async (span) => {
|
|
16
16
|
try {
|
|
17
|
-
const ctx =
|
|
17
|
+
const ctx = require_init.createTraceContext(span);
|
|
18
18
|
const originalCtx = this.ctx;
|
|
19
19
|
try {
|
|
20
20
|
this.ctx = ctx;
|
package/dist/decorators.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.cjs","names":["getConfig","createTraceContext","SpanStatusCode"],"sources":["../src/decorators.ts"],"sourcesContent":["/**\n * TypeScript 5+ Decorators for autotel\n *\n * Provides @Trace decorator for class-based code.\n *\n * **Requires TypeScript 5.0+**\n *\n * @example Method decorator\n * ```typescript\n * import { Trace } from 'autotel/decorators'\n *\n * class OrderService {\n * @Trace('order.create', { withMetrics: true })\n * async createOrder(data: OrderData) {\n * return await db.orders.create(data)\n * }\n *\n * @Trace() // Uses method name as span name\n * async processPayment(orderId: string) {\n * return await stripe.charge(orderId)\n * }\n * }\n * ```\n */\n\nimport type { TracingOptions, TraceContext } from './functional';\nimport { getConfig } from './config';\nimport { SpanStatusCode } from '@opentelemetry/api';\nimport { createTraceContext } from './trace-context';\n\n/**\n * Options for @Trace method decorator\n */\nexport interface TraceDecoratorOptions extends Omit<TracingOptions, 'name'> {\n /**\n * Custom span name. If not provided, uses the method name.\n */\n name?: string;\n}\n\n/**\n * @Trace - Method decorator for fine-grained tracing\n *\n * Wraps a class method with automatic tracing. Supports both patterns:\n * - Simple: method doesn't use ctx\n * - Advanced: method accesses ctx via this.ctx\n *\n * @example Simple usage (no ctx)\n * ```typescript\n * class OrderService {\n * @Trace()\n * async createOrder(data: OrderData) {\n * return await db.orders.create(data)\n * }\n * }\n * ```\n *\n * @example With custom name and options\n * ```typescript\n * class PaymentService {\n * @Trace('payment.charge', { withMetrics: true })\n * async chargeCard(amount: number) {\n * return await stripe.charges.create({ amount })\n * }\n * }\n * ```\n *\n * @example Accessing ctx\n * ```typescript\n * interface WithTraceContext {\n * ctx?: TraceContext\n * }\n *\n * class UserService {\n * @Trace()\n * async createUser(data: UserData) {\n * // Access ctx via this.ctx (available during execution)\n * const ctx = (this as unknown as WithTraceContext).ctx\n * if (ctx) {\n * ctx.setAttribute('user.id', data.id)\n * }\n * return await db.users.create(data)\n * }\n * }\n * ```\n */\nexport function Trace(\n options?: TraceDecoratorOptions,\n): <T extends (...args: unknown[]) => Promise<unknown>>(\n originalMethod: T,\n context: ClassMethodDecoratorContext,\n) => T;\nexport function Trace(\n name?: string,\n options?: TraceDecoratorOptions,\n): <T extends (...args: unknown[]) => Promise<unknown>>(\n originalMethod: T,\n context: ClassMethodDecoratorContext,\n) => T;\nexport function Trace(\n nameOrOptions?: string | TraceDecoratorOptions,\n maybeOptions?: TraceDecoratorOptions,\n): <T extends (...args: unknown[]) => Promise<unknown>>(\n originalMethod: T,\n context: ClassMethodDecoratorContext,\n) => T {\n // Parse arguments\n const name =\n typeof nameOrOptions === 'string' ? nameOrOptions : nameOrOptions?.name;\n // Options are used in the returned decorator function, not here\n const _options: TraceDecoratorOptions =\n typeof nameOrOptions === 'string'\n ? maybeOptions || {}\n : nameOrOptions || {};\n\n // TypeScript 5+ decorator signature\n return function <T extends (...args: unknown[]) => Promise<unknown>>(\n originalMethod: T,\n context: ClassMethodDecoratorContext,\n ): T {\n const methodName = String(context.name);\n\n // Skip if not an async function\n // Check multiple ways to detect async functions (for different transpilation environments)\n // TypeScript decorators run at class definition time, so we need robust detection\n const methodStr = originalMethod?.toString() || '';\n const isAsync =\n originalMethod &&\n (originalMethod.constructor?.name === 'AsyncFunction' ||\n methodStr.trim().startsWith('async ') ||\n (methodStr.includes('[native code]') && methodStr.includes('async')) ||\n // Fallback: if function has async in its string representation\n /async\\s+/.test(methodStr));\n\n if (!isAsync) {\n // Not an async function, return as-is\n return originalMethod;\n }\n\n const spanName = name || methodName;\n\n return async function <This>(\n this: This,\n ...args: unknown[]\n ): Promise<unknown> {\n const config = getConfig();\n const tracer = config.tracer;\n\n return tracer.startActiveSpan(spanName, async (span) => {\n try {\n // Make ctx available via this.ctx for methods that need it\n const ctx: TraceContext = createTraceContext(span);\n\n const originalCtx = (this as { ctx?: TraceContext }).ctx;\n try {\n (this as { ctx?: TraceContext }).ctx = ctx;\n const result = await originalMethod.apply(this, args as []);\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } finally {\n // Restore original ctx\n if (originalCtx === undefined) {\n delete (this as { ctx?: TraceContext }).ctx;\n } else {\n (this as { ctx?: TraceContext }).ctx = originalCtx;\n }\n }\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'Unknown error',\n });\n span.recordException(\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n } finally {\n span.end();\n }\n });\n } as T;\n };\n}\n\n// Re-export types for convenience\n\nexport { type TraceContext, type TracingOptions } from './functional';\n"],"mappings":";;;;;;AAmGA,SAAgB,MACd,eACA,cAIK;CAEL,MAAM,OACJ,OAAO,kBAAkB,WAAW,gBAAgB,eAAe;CAQrE,OAAO,SACL,gBACA,SACG;EACH,MAAM,aAAa,OAAO,QAAQ,IAAI;EAKtC,MAAM,YAAY,gBAAgB,SAAS,KAAK;EAShD,IAAI,EAPF,mBACC,eAAe,aAAa,SAAS,mBACpC,UAAU,KAAK,CAAC,CAAC,WAAW,QAAQ,KACnC,UAAU,SAAS,eAAe,KAAK,UAAU,SAAS,OAAO,KAElE,WAAW,KAAK,SAAS,KAI3B,OAAO;EAGT,MAAM,WAAW,QAAQ;EAEzB,OAAO,eAEL,GAAG,MACe;GAIlB,OAHeA,yBACK,CAAC,CAAC,OAER,gBAAgB,UAAU,OAAO,SAAS;IACtD,IAAI;KAEF,MAAM,MAAoBC,
|
|
1
|
+
{"version":3,"file":"decorators.cjs","names":["getConfig","createTraceContext","SpanStatusCode"],"sources":["../src/decorators.ts"],"sourcesContent":["/**\n * TypeScript 5+ Decorators for autotel\n *\n * Provides @Trace decorator for class-based code.\n *\n * **Requires TypeScript 5.0+**\n *\n * @example Method decorator\n * ```typescript\n * import { Trace } from 'autotel/decorators'\n *\n * class OrderService {\n * @Trace('order.create', { withMetrics: true })\n * async createOrder(data: OrderData) {\n * return await db.orders.create(data)\n * }\n *\n * @Trace() // Uses method name as span name\n * async processPayment(orderId: string) {\n * return await stripe.charge(orderId)\n * }\n * }\n * ```\n */\n\nimport type { TracingOptions, TraceContext } from './functional';\nimport { getConfig } from './config';\nimport { SpanStatusCode } from '@opentelemetry/api';\nimport { createTraceContext } from './trace-context';\n\n/**\n * Options for @Trace method decorator\n */\nexport interface TraceDecoratorOptions extends Omit<TracingOptions, 'name'> {\n /**\n * Custom span name. If not provided, uses the method name.\n */\n name?: string;\n}\n\n/**\n * @Trace - Method decorator for fine-grained tracing\n *\n * Wraps a class method with automatic tracing. Supports both patterns:\n * - Simple: method doesn't use ctx\n * - Advanced: method accesses ctx via this.ctx\n *\n * @example Simple usage (no ctx)\n * ```typescript\n * class OrderService {\n * @Trace()\n * async createOrder(data: OrderData) {\n * return await db.orders.create(data)\n * }\n * }\n * ```\n *\n * @example With custom name and options\n * ```typescript\n * class PaymentService {\n * @Trace('payment.charge', { withMetrics: true })\n * async chargeCard(amount: number) {\n * return await stripe.charges.create({ amount })\n * }\n * }\n * ```\n *\n * @example Accessing ctx\n * ```typescript\n * interface WithTraceContext {\n * ctx?: TraceContext\n * }\n *\n * class UserService {\n * @Trace()\n * async createUser(data: UserData) {\n * // Access ctx via this.ctx (available during execution)\n * const ctx = (this as unknown as WithTraceContext).ctx\n * if (ctx) {\n * ctx.setAttribute('user.id', data.id)\n * }\n * return await db.users.create(data)\n * }\n * }\n * ```\n */\nexport function Trace(\n options?: TraceDecoratorOptions,\n): <T extends (...args: unknown[]) => Promise<unknown>>(\n originalMethod: T,\n context: ClassMethodDecoratorContext,\n) => T;\nexport function Trace(\n name?: string,\n options?: TraceDecoratorOptions,\n): <T extends (...args: unknown[]) => Promise<unknown>>(\n originalMethod: T,\n context: ClassMethodDecoratorContext,\n) => T;\nexport function Trace(\n nameOrOptions?: string | TraceDecoratorOptions,\n maybeOptions?: TraceDecoratorOptions,\n): <T extends (...args: unknown[]) => Promise<unknown>>(\n originalMethod: T,\n context: ClassMethodDecoratorContext,\n) => T {\n // Parse arguments\n const name =\n typeof nameOrOptions === 'string' ? nameOrOptions : nameOrOptions?.name;\n // Options are used in the returned decorator function, not here\n const _options: TraceDecoratorOptions =\n typeof nameOrOptions === 'string'\n ? maybeOptions || {}\n : nameOrOptions || {};\n\n // TypeScript 5+ decorator signature\n return function <T extends (...args: unknown[]) => Promise<unknown>>(\n originalMethod: T,\n context: ClassMethodDecoratorContext,\n ): T {\n const methodName = String(context.name);\n\n // Skip if not an async function\n // Check multiple ways to detect async functions (for different transpilation environments)\n // TypeScript decorators run at class definition time, so we need robust detection\n const methodStr = originalMethod?.toString() || '';\n const isAsync =\n originalMethod &&\n (originalMethod.constructor?.name === 'AsyncFunction' ||\n methodStr.trim().startsWith('async ') ||\n (methodStr.includes('[native code]') && methodStr.includes('async')) ||\n // Fallback: if function has async in its string representation\n /async\\s+/.test(methodStr));\n\n if (!isAsync) {\n // Not an async function, return as-is\n return originalMethod;\n }\n\n const spanName = name || methodName;\n\n return async function <This>(\n this: This,\n ...args: unknown[]\n ): Promise<unknown> {\n const config = getConfig();\n const tracer = config.tracer;\n\n return tracer.startActiveSpan(spanName, async (span) => {\n try {\n // Make ctx available via this.ctx for methods that need it\n const ctx: TraceContext = createTraceContext(span);\n\n const originalCtx = (this as { ctx?: TraceContext }).ctx;\n try {\n (this as { ctx?: TraceContext }).ctx = ctx;\n const result = await originalMethod.apply(this, args as []);\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } finally {\n // Restore original ctx\n if (originalCtx === undefined) {\n delete (this as { ctx?: TraceContext }).ctx;\n } else {\n (this as { ctx?: TraceContext }).ctx = originalCtx;\n }\n }\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'Unknown error',\n });\n span.recordException(\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n } finally {\n span.end();\n }\n });\n } as T;\n };\n}\n\n// Re-export types for convenience\n\nexport { type TraceContext, type TracingOptions } from './functional';\n"],"mappings":";;;;;;AAmGA,SAAgB,MACd,eACA,cAIK;CAEL,MAAM,OACJ,OAAO,kBAAkB,WAAW,gBAAgB,eAAe;CAQrE,OAAO,SACL,gBACA,SACG;EACH,MAAM,aAAa,OAAO,QAAQ,IAAI;EAKtC,MAAM,YAAY,gBAAgB,SAAS,KAAK;EAShD,IAAI,EAPF,mBACC,eAAe,aAAa,SAAS,mBACpC,UAAU,KAAK,CAAC,CAAC,WAAW,QAAQ,KACnC,UAAU,SAAS,eAAe,KAAK,UAAU,SAAS,OAAO,KAElE,WAAW,KAAK,SAAS,KAI3B,OAAO;EAGT,MAAM,WAAW,QAAQ;EAEzB,OAAO,eAEL,GAAG,MACe;GAIlB,OAHeA,yBACK,CAAC,CAAC,OAER,gBAAgB,UAAU,OAAO,SAAS;IACtD,IAAI;KAEF,MAAM,MAAoBC,gCAAmB,IAAI;KAEjD,MAAM,cAAe,KAAgC;KACrD,IAAI;MACF,AAAC,KAAgC,MAAM;MACvC,MAAM,SAAS,MAAM,eAAe,MAAM,MAAM,IAAU;MAC1D,KAAK,UAAU,EAAE,MAAMC,kCAAe,GAAG,CAAC;MAC1C,OAAO;KACT,UAAU;MAER,IAAI,gBAAgB,QAClB,OAAQ,KAAgC;WAExC,AAAC,KAAgC,MAAM;KAE3C;IACF,SAAS,OAAO;KACd,KAAK,UAAU;MACb,MAAMA,kCAAe;MACrB,SAAS,iBAAiB,QAAQ,MAAM,UAAU;KACpD,CAAC;KACD,KAAK,gBACH,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAC1D;KACA,MAAM;IACR,UAAU;KACR,KAAK,IAAI;IACX;GACF,CAAC;EACH;CACF;AACF"}
|
package/dist/decorators.js
CHANGED
package/dist/event.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const
|
|
2
|
+
const require_init = require('./init-C3RApHKJ.cjs');
|
|
3
3
|
|
|
4
|
-
exports.Event =
|
|
5
|
-
exports.getEvents =
|
|
6
|
-
exports.resetEvents =
|
|
4
|
+
exports.Event = require_init.Event;
|
|
5
|
+
exports.getEvents = require_init.getEvents;
|
|
6
|
+
exports.resetEvents = require_init.resetEvents;
|
package/dist/event.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { getForceFlushableProvider } from "./tracer-provider.js";
|
|
2
2
|
import { getConfig } from "./config.js";
|
|
3
3
|
import { AUTOTEL_SAMPLING_RATE, AUTOTEL_SAMPLING_TAIL_EVALUATED, AUTOTEL_SAMPLING_TAIL_KEEP, AlwaysSampler } from "./sampling.js";
|
|
4
|
-
import {
|
|
5
|
-
import { g as getContextStorage, h as getActiveContextWithBaggage, p as createTraceContext, t as getEventQueue } from "./track-BBcxEJEC.js";
|
|
4
|
+
import { D as getActiveContextWithBaggage, O as getContextStorage, T as createTraceContext, h as getEventQueue, m as runInOperationContext, r as getSdk, t as getConfig$1 } from "./init-R-gSEXkJ.js";
|
|
6
5
|
import { setSpanName } from "./trace-helpers.js";
|
|
7
|
-
import { n as runInOperationContext } from "./operation-context-CKBoA4Qy.js";
|
|
8
6
|
import { SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
9
7
|
import * as nodeFs from "node:fs";
|
|
10
8
|
import * as nodeUrl from "node:url";
|
|
@@ -837,4 +835,4 @@ function withBaggage(options) {
|
|
|
837
835
|
|
|
838
836
|
//#endregion
|
|
839
837
|
export { trace$1 as a, withTracing as c, span as i, getActiveTraceContext as n, withBaggage as o, instrument as r, withNewContext as s, ctx as t };
|
|
840
|
-
//# sourceMappingURL=functional-
|
|
838
|
+
//# sourceMappingURL=functional-BnDUxnSl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"functional-Bit6noRu.js","names":["getInitConfig","otelTrace","trace"],"sources":["../src/variable-name-inference.ts","../src/functional.ts"],"sourcesContent":["/**\n * Variable Name Inference Utility\n *\n * Attempts to infer variable names from const/export const assignments\n * by analyzing the call stack and parsing source code.\n *\n * This is a best-effort approach with graceful degradation - if inference\n * fails for any reason, it returns undefined without breaking the application.\n */\n\n// namespace imports for browser-bundler compat — see node-require.ts\nimport * as nodeFs from 'node:fs';\nimport * as nodeUrl from 'node:url';\n\ninterface CallLocation {\n file: string;\n line: number;\n column: number;\n}\n\n/**\n * LRU Cache for inferred variable names\n * Key: \"file:line\" (e.g., \"/path/to/file.ts:42\")\n * Value: inferred variable name or undefined\n */\nconst inferenceCache = new Map<string, string | undefined>();\nconst MAX_CACHE_SIZE = 50;\n\n/**\n * Captures the current call stack\n */\nfunction captureStackTrace(): string {\n const originalStackTraceLimit = Error.stackTraceLimit;\n Error.stackTraceLimit = 10; // Only need first few frames\n\n const err = new Error('Stack trace capture');\n const stack = err.stack || '';\n\n Error.stackTraceLimit = originalStackTraceLimit;\n return stack;\n}\n\n/**\n * Parses the stack trace to find where trace() was called\n *\n * Stack trace format (Node.js):\n * at functionName (file:line:column)\n * at file:line:column\n *\n * We skip frames until we find one that's NOT in functional.ts or this file.\n * We also need to skip one additional frame (the trace/span/instrument function itself)\n * to get to the actual user code.\n */\nfunction parseCallLocation(stack: string): CallLocation | undefined {\n const lines = stack.split('\\n');\n let skippedExternalFrame = false;\n\n for (const line of lines) {\n // Skip if line contains this file or functional.ts (internal frames)\n // Be specific about the filename to avoid matching test files\n if (\n line.includes('variable-name-inference.ts') ||\n line.includes('variable-name-inference.js') ||\n line.includes('functional.ts') ||\n line.includes('functional.js')\n ) {\n continue;\n }\n\n // Match various stack trace formats\n // Format 1: at functionName (file:line:column)\n // Format 2: at file:line:column\n const match =\n line.match(/at\\s+(?:.*\\s+)?\\(?([^:]+):(\\d+):(\\d+)\\)?/) ||\n line.match(/^.*?([^:]+):(\\d+):(\\d+)/);\n\n if (match) {\n let filePath = match[1]!.trim();\n\n // Handle file:// URLs (convert to paths)\n if (filePath.startsWith('file://')) {\n try {\n filePath = nodeUrl.fileURLToPath(filePath);\n } catch {\n continue;\n }\n }\n\n // Skip the first external frame (the trace/span function itself)\n // We want the frame where the user CALLS trace(), not inside trace()\n if (!skippedExternalFrame) {\n skippedExternalFrame = true;\n continue;\n }\n\n return {\n file: filePath,\n line: Number.parseInt(match[2]!, 10),\n column: Number.parseInt(match[3]!, 10),\n };\n }\n }\n\n return undefined;\n}\n\n/**\n * Reads a specific line from a source file\n */\nfunction readSourceLine(\n filePath: string,\n lineNumber: number,\n): string | undefined {\n try {\n // Check if we can access the file system (not available in edge runtimes)\n if (typeof nodeFs.readFileSync !== 'function') {\n return undefined;\n }\n\n const content = nodeFs.readFileSync(filePath, 'utf8');\n const lines = content.split('\\n');\n\n // Line numbers are 1-based\n return lines[lineNumber - 1];\n } catch {\n // File doesn't exist, permission denied, or other error\n return undefined;\n }\n}\n\n/**\n * Extracts variable name from source code line using regex patterns\n *\n * Supported patterns:\n * - const varName = anyFunction(\n * - export const varName = anyFunction(\n * - let varName = anyFunction(\n * - var varName = anyFunction(\n *\n * Note: This won't work with destructuring assignments or complex patterns\n */\nfunction extractVariableName(sourceLine: string): string | undefined {\n // Remove leading/trailing whitespace\n const trimmed = sourceLine.trim();\n\n // Pattern: (export)? (const|let|var) varName = anyFunctionCall(\n // We match any function call, not just trace(), to support wrapper functions\n const patterns = [\n // export const varName = anyFunction(\n /export\\s+const\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n // const varName = anyFunction(\n /const\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n // export let varName = anyFunction(\n /export\\s+let\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n // let varName = anyFunction(\n /let\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n // export var varName = anyFunction(\n /export\\s+var\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n // var varName = anyFunction(\n /var\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n ];\n\n for (const pattern of patterns) {\n const match = trimmed.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return undefined;\n}\n\n/**\n * Adds an entry to the cache with LRU eviction\n */\nfunction cacheInference(key: string, value: string | undefined): void {\n // If cache is full, remove oldest entry (first entry in Map)\n if (inferenceCache.size >= MAX_CACHE_SIZE) {\n const firstKey = inferenceCache.keys().next().value;\n if (firstKey) {\n inferenceCache.delete(firstKey);\n }\n }\n\n inferenceCache.set(key, value);\n}\n\n/**\n * Main entry point: Attempts to infer the variable name from the call stack\n *\n * This function:\n * 1. Captures the call stack\n * 2. Parses it to find where trace() was called (file + line)\n * 3. Reads that line from the source file\n * 4. Extracts the variable name using regex\n *\n * Returns undefined if inference fails at any step (graceful degradation).\n * Results are cached to avoid repeated file I/O.\n *\n * @returns The inferred variable name, or undefined if inference failed\n */\nexport function inferVariableNameFromCallStack(): string | undefined {\n try {\n // Capture stack trace\n const stack = captureStackTrace();\n\n // Parse stack to find trace() call location\n const callLocation = parseCallLocation(stack);\n if (!callLocation) {\n return undefined;\n }\n\n // Check cache\n const cacheKey = `${callLocation.file}:${callLocation.line}`;\n if (inferenceCache.has(cacheKey)) {\n return inferenceCache.get(cacheKey);\n }\n\n // Read source line\n const sourceLine = readSourceLine(callLocation.file, callLocation.line);\n if (!sourceLine) {\n return undefined;\n }\n\n // Extract variable name\n const variableName = extractVariableName(sourceLine);\n\n // Cache result (even if undefined, to avoid repeated failed attempts)\n cacheInference(cacheKey, variableName);\n\n return variableName;\n } catch {\n // Graceful degradation - don't break the app if inference fails\n return undefined;\n }\n}\n\n/**\n * Clears the inference cache (useful for testing)\n */\nexport function clearInferenceCache(): void {\n inferenceCache.clear();\n}\n","/**\n * Functional API for non-class code\n *\n * Three approaches for different use cases:\n * 1. trace() - Zero-ceremony HOF for single functions\n * 2. withTracing() - Middleware-style composable wrapper\n * 3. instrument() - Batch auto-instrumentation for modules\n *\n * @example trace() - Single function\n * ```typescript\n * export const createUser = trace(async (data) => {\n * getActiveTraceContext()?.setAttribute('user.id', data.id)\n * return await db.users.create(data)\n * })\n * ```\n *\n * @example withTracing() - Composable middleware\n * ```typescript\n * export const createUser = withTracing({\n * name: 'user.create'\n * })(ctx => async (data) => {\n * ctx.setAttribute('user.id', data.id)\n * return await db.users.create(data)\n * })\n * ```\n *\n * @example instrument() - Batch instrumentation\n * ```typescript\n * export default instrument({\n * createUser: async (data) => { },\n * updateUser: async (id, data) => { }\n * }, { serviceName: 'user' })\n * ```\n */\n\nimport {\n SpanStatusCode,\n trace as otelTrace,\n context,\n propagation,\n type Span,\n type Counter,\n type Histogram,\n type Attributes,\n} from '@opentelemetry/api';\nimport { getConfig } from './config';\nimport { getConfig as getInitConfig, getSdk } from './init';\nimport { getForceFlushableProvider } from './tracer-provider';\nimport {\n type Sampler,\n type SamplingContext,\n AlwaysSampler,\n AUTOTEL_SAMPLING_TAIL_KEEP,\n AUTOTEL_SAMPLING_TAIL_EVALUATED,\n AUTOTEL_SAMPLING_RATE,\n} from './sampling';\nimport { getEventQueue } from './track';\nimport type { TraceContext } from './trace-context';\nimport {\n createTraceContext,\n getActiveContextWithBaggage,\n getContextStorage,\n} from './trace-context';\nimport { setSpanName } from './trace-helpers';\nimport { runInOperationContext } from './operation-context';\nimport { inferVariableNameFromCallStack } from './variable-name-inference';\n\n/**\n * Complete trace context containing trace identifiers and span methods\n *\n * The ctx parameter in trace() functions provides:\n * - traceId, spanId, correlationId from the active span\n * - Span manipulation methods (setAttribute, setAttributes, setStatus, recordException)\n *\n * For custom context, access it directly in your functions (standard OpenTelemetry pattern).\n *\n * @example\n * ```typescript\n * import { trace } from 'autotel'\n *\n * export const createUser = withTracing({})((ctx) => async (data: CreateUserData) => {\n * // Get custom context directly (standard OTel approach)\n * const userId = getCurrentUserId()\n * const tenantId = getCurrentTenant()\n *\n * // Use ctx for span operations and trace IDs\n * ctx.setAttribute('user.id', data.id)\n * ctx.setAttribute('user.tenant', tenantId)\n * console.log(ctx.traceId) // Trace IDs available\n * })\n * ```\n */\nexport type { TraceContext } from './trace-context';\n\nlet unknownSpanNameWarningEmitted = false;\n\ntype WrappedFunction<TArgs extends unknown[], TReturn> = (\n ...args: TArgs\n) => TReturn | Promise<TReturn>;\n\nfunction resolveVariableName(\n named: InstrumentableFunction,\n variableName?: string,\n): string | undefined {\n const suppliedFunctionName = inferFunctionName(named);\n const callStackVariableName = suppliedFunctionName\n ? undefined\n : inferVariableNameFromCallStack();\n return variableName || suppliedFunctionName || callStackVariableName;\n}\n\n/**\n * Wrap an explicit context factory `(ctx) => (...args) => result`.\n * Used by {@link withTracing}; the input is a factory by contract, so there is\n * no plain-vs-factory detection. The factory is never invoked at construction\n * time — only when the wrapper is called.\n */\nfunction wrapFactoryWithTracing<TArgs extends unknown[], TReturn>(\n factory: (\n ctx: TraceContext,\n ) => (...args: TArgs) => TReturn | Promise<TReturn>,\n options: TracingOptions<TArgs, TReturn>,\n variableName?: string,\n): WrappedFunction<TArgs, TReturn> {\n const effectiveVariableName = resolveVariableName(\n factory as InstrumentableFunction,\n variableName,\n );\n return wrapWithTracingSync(\n factory,\n options,\n effectiveVariableName,\n ) as WrappedFunction<TArgs, TReturn>;\n}\n\n/**\n * Wrap a plain function `(...args) => result`. Used by {@link trace} and\n * {@link instrument}: the function receives its real arguments and no context\n * is injected. Reach the active span via {@link getActiveTraceContext} inside\n * the body (or any helper it calls).\n */\nfunction wrapPlainWithTracing<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => TReturn | Promise<TReturn>,\n options: TracingOptions<TArgs, TReturn>,\n variableName?: string,\n): WrappedFunction<TArgs, TReturn> {\n const effectiveVariableName = resolveVariableName(\n fn as InstrumentableFunction,\n variableName,\n );\n const factory = (_ctx: TraceContext) => fn;\n return wrapWithTracingSync(\n factory,\n options,\n effectiveVariableName,\n ) as WrappedFunction<TArgs, TReturn>;\n}\n\n/**\n * Common options for functional tracing\n */\nexport interface TracingOptions<\n TArgs extends unknown[] = unknown[],\n TReturn = unknown,\n> {\n /**\n * Span name (highest priority)\n * If provided, this is used as the span name\n */\n name?: string;\n\n /**\n * Service name (used to compose final span name)\n * If name not provided, span name becomes: ${serviceName}.${functionName}\n */\n serviceName?: string;\n\n /**\n * Sampling strategy\n * @default AlwaysSampler\n */\n sampler?: Sampler;\n\n /**\n * Enable metrics collection (counter, histogram)\n * @default false\n */\n withMetrics?: boolean;\n\n /**\n * Extract attributes from function arguments\n */\n attributesFromArgs?: (args: TArgs) => Record<string, unknown>;\n\n /**\n * Extract attributes from function result\n */\n attributesFromResult?: (result: TReturn) => Record<string, unknown>;\n\n /**\n * Capture the function arguments onto the span as `autotel.input`\n * (JSON, truncated). One arg is captured directly; multiple are captured as\n * an array. Off by default — opt in per call. Tools (visualizers, devtools)\n * read this alongside `ai.toolCall.args` to show function I/O uniformly.\n * Avoid on args with secrets/PII, or pair with a redacting processor.\n */\n captureInput?: boolean;\n\n /**\n * Capture the function return value onto the span as `autotel.output`\n * (JSON, truncated). Off by default. Same caveats as {@link captureInput}.\n */\n captureOutput?: boolean;\n\n /**\n * Start a new root span instead of creating a child\n * Useful for serverless entry points\n * @default false\n */\n startNewRoot?: boolean;\n\n /**\n * Flush events queue when span ends\n * Only flushes on root spans (to avoid excessive flushing)\n * @default true\n */\n flushOnRootSpanEnd?: boolean;\n\n /**\n * Span kind for semantic convention compliance\n * Used for messaging (PRODUCER/CONSUMER), HTTP (CLIENT/SERVER), etc.\n * @default SpanKind.INTERNAL\n */\n spanKind?: import('@opentelemetry/api').SpanKind;\n\n /**\n * Classify a thrown value as a real error. Return `false` to treat the throw\n * as expected control flow: the span is marked OK, no exception is recorded,\n * and the value is rethrown untouched. Use this for framework control-flow\n * signals that propagate via `throw` but are not failures — e.g. TanStack\n * Router / Next.js `redirect()` and `notFound()`.\n * @default every throw is treated as an error\n */\n isError?: (error: unknown) => boolean;\n}\n\n/**\n * Options for instrument() batch instrumentation\n */\nexport interface InstrumentOptions<\n T extends Record<string, AnyInstrumentable> = Record<\n string,\n AnyInstrumentable\n >,\n> extends TracingOptions {\n /** Object whose function properties should be instrumented */\n functions: T;\n /**\n * Per-function configuration overrides\n */\n overrides?: Record<string, Partial<TracingOptions>>;\n\n /**\n * Functions to skip (won't be instrumented)\n * Supports:\n * - String keys: 'functionName'\n * - RegExp: /^_internal/\n * - Predicate: (key, fn) => boolean\n *\n * By default, functions starting with _ are skipped\n */\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n skip?: (string | RegExp | ((key: string, fn: Function) => boolean))[];\n}\n\n/**\n * Options for instrumenting one function with an explicit stable key.\n */\nexport interface SingleInstrumentOptions<\n TFunction extends AnyInstrumentable = AnyInstrumentable,\n> extends TracingOptions {\n /** Stable function key used for span naming */\n key: string;\n /** Function to instrument */\n fn: TFunction;\n}\n\n// Maximum error message length to prevent span bloat\nconst MAX_ERROR_MESSAGE_LENGTH = 500;\n\nfunction createDummyCtx<\n TBaggage extends Record<string, unknown> | undefined = undefined,\n>(): TraceContext<TBaggage> {\n // `recordException` / `addEvent` are no-op shims kept for the same\n // compatibility window as `createTraceContext` (see trace-context.ts).\n return {\n traceId: '',\n spanId: '',\n correlationId: '',\n setAttribute: () => {},\n setAttributes: () => {},\n setStatus: () => {},\n recordException: () => {},\n addEvent: () => {},\n addLink: () => {},\n addLinks: () => {},\n updateName: () => {},\n isRecording: () => false,\n getBaggage: () => {},\n setBaggage: () => '',\n deleteBaggage: () => {},\n getAllBaggage: () => new Map(),\n } as unknown as TraceContext<TBaggage>;\n}\n\n/** Attribute keys for opt-in function I/O capture (see TracingOptions). */\nconst AUTOTEL_INPUT_ATTR = 'autotel.input';\nconst AUTOTEL_OUTPUT_ATTR = 'autotel.output';\nconst CAPTURE_MAX_CHARS = 4096;\n\n/** JSON-serialize a captured value, defensively (truncate, swallow cycles). */\nfunction serializeCapture(value: unknown): string | undefined {\n if (value === undefined) return undefined;\n try {\n const json = typeof value === 'string' ? value : JSON.stringify(value);\n if (json === undefined) return undefined;\n return json.length > CAPTURE_MAX_CHARS\n ? `${json.slice(0, CAPTURE_MAX_CHARS)}…[truncated]`\n : json;\n } catch {\n return undefined;\n }\n}\n\n/** `autotel.input` from args (single arg captured directly, else the array). */\nfunction captureInputAttrs(\n args: unknown[],\n enabled?: boolean,\n): Record<string, unknown> {\n if (!enabled) return {};\n const s = serializeCapture(args.length === 1 ? args[0] : args);\n return s === undefined ? {} : { [AUTOTEL_INPUT_ATTR]: s };\n}\n\n/** `autotel.output` from the return value. */\nfunction captureOutputAttrs(\n result: unknown,\n enabled?: boolean,\n): Record<string, unknown> {\n if (!enabled) return {};\n const s = serializeCapture(result);\n return s === undefined ? {} : { [AUTOTEL_OUTPUT_ATTR]: s };\n}\n\n// Symbol to prevent double-instrumentation (idempotency flag)\nconst INSTRUMENTED_SYMBOL = Symbol.for('autotel.functional.instrumented');\n\ntype InstrumentedFlag = {\n [INSTRUMENTED_SYMBOL]?: true;\n};\n\nfunction hasInstrumentationFlag(value: unknown): value is InstrumentedFlag {\n return (\n (typeof value === 'function' || typeof value === 'object') &&\n value !== null &&\n Boolean((value as InstrumentedFlag)[INSTRUMENTED_SYMBOL])\n );\n}\n\n/**\n * Truncate error message to prevent span bloat\n */\nfunction truncateErrorMessage(message: string): string {\n if (message.length <= MAX_ERROR_MESSAGE_LENGTH) {\n return message;\n }\n return `${message.slice(0, MAX_ERROR_MESSAGE_LENGTH)}... (truncated)`;\n}\n\n/** Per-invocation state the terminal span handlers close over. */\ninterface SpanFinalizeContext {\n span: Span;\n spanName: string;\n duration: number;\n callCounter?: Counter;\n durationHistogram?: Histogram;\n handleTailSampling: (\n success: boolean,\n duration: number,\n error?: Error,\n ) => void;\n /** Extra attributes to merge (e.g. captured args); absent on immediate-exec paths. */\n extraAttributes?: Attributes;\n}\n\n/**\n * Terminal handling for a value thrown by a traced function. Shared by all four\n * `trace()` execution paths (immediate + wrapper, sync + async) so the outcome\n * rules live in exactly one place. Ends the span; the caller flushes (await/void)\n * and rethrows.\n *\n * If `isError` classifies the throw as expected control flow — e.g. a framework\n * `redirect()` / `notFound()` signal — it is recorded as a success outcome with\n * an OK status and no exception. Otherwise it is recorded as an error.\n */\nfunction finalizeThrownSpan(\n error: unknown,\n isError: ((error: unknown) => boolean) | undefined,\n ctx: SpanFinalizeContext,\n): void {\n const {\n span,\n spanName,\n duration,\n callCounter,\n durationHistogram,\n handleTailSampling,\n extraAttributes,\n } = ctx;\n\n const baseAttributes: Attributes = {\n ...extraAttributes,\n 'operation.name': spanName,\n 'code.function': spanName,\n 'operation.duration': duration,\n };\n\n if (isError && !isError(error)) {\n callCounter?.add(1, { operation: spanName, status: 'success' });\n durationHistogram?.record(duration, {\n operation: spanName,\n status: 'success',\n });\n span.setStatus({ code: SpanStatusCode.OK });\n span.setAttributes({ ...baseAttributes, 'operation.success': true });\n handleTailSampling(true, duration);\n span.end();\n return;\n }\n\n callCounter?.add(1, { operation: spanName, status: 'error' });\n durationHistogram?.record(duration, { operation: spanName, status: 'error' });\n\n const truncatedMessage = truncateErrorMessage(\n error instanceof Error ? error.message : 'Unknown error',\n );\n\n span.setStatus({ code: SpanStatusCode.ERROR, message: truncatedMessage });\n span.setAttributes({\n ...baseAttributes,\n 'operation.success': false,\n error: true,\n 'exception.type': error instanceof Error ? error.constructor.name : 'Error',\n 'exception.message': truncatedMessage,\n });\n if (error instanceof Error && error.stack) {\n span.setAttribute(\n 'exception.stack',\n error.stack.slice(0, MAX_ERROR_MESSAGE_LENGTH),\n );\n }\n const thrown = error instanceof Error ? error : new Error(String(error));\n span.recordException(thrown);\n // Samplers read result.error, so hand them a real Error rather than\n // whatever the code threw.\n handleTailSampling(false, duration, thrown);\n span.end();\n}\n\ntype InstrumentableFunction<\n TArgs extends unknown[] = unknown[],\n TReturn = unknown,\n> = ((...args: TArgs) => TReturn | Promise<TReturn>) & {\n displayName?: string;\n name?: string;\n};\n\n/**\n * Constraint alias for `instrument()` and friends. `never[]` parameters make\n * every concretely-typed function (e.g. `(name: string) => Promise<User>`)\n * satisfy the constraint under `strictFunctionTypes` without resorting to\n * `any`. Use ONLY in constraint positions — the concrete `T` is still\n * inferred from the actual argument, so call-site argument and return types\n * are fully preserved.\n */\ntype AnyInstrumentable = ((...args: never[]) => unknown) & {\n displayName?: string;\n name?: string;\n};\n\n/**\n * Try to infer function name from function properties\n * Checks for displayName, name, or other metadata that might be set\n */\nfunction inferFunctionName<\n TArgs extends unknown[] = unknown[],\n TReturn = unknown,\n>(fn: InstrumentableFunction<TArgs, TReturn>): string | undefined {\n // Check for displayName property (sometimes set by bundlers)\n const displayName = (fn as { displayName?: string }).displayName;\n if (displayName) {\n return displayName;\n }\n\n // Check function.name (works for named functions and modern arrow function assignment)\n // Note: Empty string is falsy, so this handles both undefined and ''\n if (fn.name && fn.name !== 'anonymous' && fn.name !== '') {\n return fn.name;\n }\n\n // Try to extract name from function source (for function declarations)\n const source = Function.prototype.toString.call(fn);\n const match = source.match(/function\\s+([^(\\s]+)/);\n if (match && match[1] && match[1] !== 'anonymous') {\n return match[1];\n }\n\n return undefined;\n}\n\n/**\n * Determine span name using priority:\n * 1. Explicit name option\n * 2. serviceName + functionName\n * 3. Inferred from function/variable name (including stack trace fallback)\n * 4. Fallback to 'unknown'\n */\nfunction getSpanName<TArgs extends unknown[], TReturn>(\n options: TracingOptions<TArgs, TReturn>,\n fn: InstrumentableFunction<TArgs, TReturn>,\n variableName?: string,\n): string {\n // 1. Explicit name\n if (options.name) {\n return options.name;\n }\n\n // 2. Try variable name, function name, or function properties\n let fnName = variableName || inferFunctionName(fn);\n\n // Default to 'anonymous' if still no name\n fnName = fnName || 'anonymous';\n\n // 2. serviceName + functionName\n if (options.serviceName) {\n return `${options.serviceName}.${fnName}`;\n }\n\n // 3. Inferred from function name\n if (fnName && fnName !== 'anonymous') {\n return fnName;\n }\n\n // 4. Fallback\n const initConfig = getInitConfig();\n if (\n typeof process !== 'undefined' &&\n process.env.NODE_ENV !== 'production' &&\n !unknownSpanNameWarningEmitted &&\n initConfig?.logger?.warn\n ) {\n unknownSpanNameWarningEmitted = true;\n initConfig.logger.warn(\n {},\n '[autotel] Span name resolved to \"unknown\". Pass an explicit name, for example trace(\"operation.name\", fn).',\n );\n }\n return 'unknown';\n}\n\n/**\n * Check if function should be skipped\n */\nfunction shouldSkip(\n key: string,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n fn: Function,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n skip?: (string | RegExp | ((key: string, fn: Function) => boolean))[],\n): boolean {\n // Default: skip functions starting with _\n if (key.startsWith('_')) {\n return true;\n }\n\n if (!skip || skip.length === 0) {\n return false;\n }\n\n for (const rule of skip) {\n if (typeof rule === 'string' && key === rule) {\n return true;\n } else if (rule instanceof RegExp && rule.test(key)) {\n return true;\n } else if (typeof rule === 'function' && rule(key, fn)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Get current trace context value (internal helper)\n *\n * Returns base context (trace IDs) + span methods from the active span.\n */\nfunction getCtxValue<\n TBaggage extends Record<string, unknown> | undefined = undefined,\n>(): TraceContext<TBaggage> | null {\n const activeSpan = otelTrace.getActiveSpan();\n if (!activeSpan) return null;\n\n // Use shared utility to create trace context\n return createTraceContext<TBaggage>(activeSpan);\n}\n\n/**\n * Get the autotel {@link TraceContext} for the currently active span.\n *\n * This is the ambient accessor for the functional API: instead of threading a\n * `ctx` parameter through a factory, call this inside any traced function (or a\n * helper it calls) to reach `setAttribute`, `setUser`, `getBaggage`, and the\n * rest of the context surface. Returns `undefined` when no span is active.\n *\n * @example\n * ```typescript\n * const getUser = trace('getUser', async (id: string) => {\n * getActiveTraceContext()?.setAttribute('user.id', id);\n * return db.users.find(id);\n * });\n * ```\n *\n * @see getActiveSpan for the raw OpenTelemetry span\n * @see getRequestLogger which reads the active context when called with no args\n */\nexport function getActiveTraceContext<\n TBaggage extends Record<string, unknown> | undefined = undefined,\n>(): TraceContext<TBaggage> | undefined {\n return getCtxValue<TBaggage>() ?? undefined;\n}\n\n/**\n * Context object that lazily evaluates the active span on property access\n *\n * Access trace context directly without function call syntax.\n *\n * @example\n * ```typescript\n * import { trace, ctx } from 'autotel'\n *\n * export const createUser = trace(async (data) => {\n * // Direct property access - no function call!\n * if (ctx.traceId) {\n * ctx.setAttribute('user.id', data.id)\n * console.log('Trace:', ctx.traceId)\n * }\n * })\n * ```\n */\nexport const ctx = new Proxy({} as TraceContext, {\n get(_target, prop) {\n const ctxValue = getCtxValue();\n if (!ctxValue) {\n return;\n }\n return ctxValue[prop as keyof typeof ctxValue];\n },\n\n has(_target, prop) {\n const ctxValue = getCtxValue();\n if (!ctxValue) {\n return false;\n }\n return prop in ctxValue;\n },\n\n ownKeys() {\n const ctxValue = getCtxValue();\n if (!ctxValue) {\n return [];\n }\n return Object.keys(ctxValue);\n },\n\n getOwnPropertyDescriptor(_target, prop) {\n const ctxValue = getCtxValue();\n if (!ctxValue) {\n return;\n }\n return Object.getOwnPropertyDescriptor(ctxValue, prop);\n },\n});\n\n/**\n * Build the root-operation flush policy once and reuse it for wrapped and\n * immediate execution. Async operations await this function; sync operations\n * trigger it without blocking.\n */\nfunction createRootTelemetryFlusher(\n options: Pick<TracingOptions, 'flushOnRootSpanEnd'>,\n isRootSpan: boolean,\n): () => Promise<void> {\n const initConfig = getInitConfig();\n const shouldFlush =\n options.flushOnRootSpanEnd ?? initConfig?.flushOnRootSpanEnd ?? true;\n const shouldFlushSpans = initConfig?.forceFlushOnShutdown ?? false;\n\n return async () => {\n if (!shouldFlush || !isRootSpan) return;\n\n try {\n const queue = getEventQueue();\n if (queue && queue.size() > 0) {\n await queue.flush();\n }\n\n if (shouldFlushSpans) {\n const tracerProvider = getForceFlushableProvider(getSdk());\n await tracerProvider?.forceFlush();\n }\n } catch (error) {\n const logger = getInitConfig()?.logger;\n logger?.error?.(\n { err: error instanceof Error ? error : undefined },\n `[autotel] Auto-flush failed${error instanceof Error ? '' : `: ${String(error)}`}`,\n );\n }\n };\n}\n\n/**\n * Give every root operation its own baggage context without replacing a\n * caller's existing scope. AsyncLocalStorage keeps the scope alive until an\n * async result settles and restores the previous store afterwards.\n */\nfunction runWithTraceContextStorage<TResult>(fn: () => TResult): TResult {\n const storage = getContextStorage();\n if (storage.getStore()) return fn();\n return storage.run({ value: context.active() }, fn);\n}\n\n/**\n * Core tracing wrapper for sync functions (internal implementation)\n */\nfunction wrapWithTracingSync<TArgs extends unknown[], TReturn>(\n fnFactory: (\n ctx: TraceContext,\n ) => (...args: TArgs) => TReturn | Promise<TReturn>,\n options: TracingOptions<TArgs, TReturn>,\n variableName?: string,\n): WrappedFunction<TArgs, TReturn> {\n // Idempotency check: if already instrumented, return as-is\n if (hasInstrumentationFlag(fnFactory)) {\n // If already instrumented, we need to extract the original factory\n // For now, we'll just proceed - this edge case is handled by the wrapped function check\n }\n\n const config = getConfig();\n const tracer = config.tracer;\n const meter = config.meter;\n // Annotate as Sampler so the optional hooks stay visible. Inference would\n // narrow to AlwaysSampler and hide them behind `in` checks.\n const sampler: Sampler = options.sampler || new AlwaysSampler();\n\n const spanName = getSpanName(\n options,\n fnFactory as unknown as InstrumentableFunction<TArgs, TReturn>,\n variableName,\n );\n\n // Metrics setup (if enabled)\n const callCounter = options.withMetrics\n ? meter.createCounter(`${spanName}.calls`, {\n description: `Call count for ${spanName}`,\n unit: '1',\n })\n : undefined;\n\n const durationHistogram = options.withMetrics\n ? meter.createHistogram(`${spanName}.duration`, {\n description: `Duration for ${spanName}`,\n unit: 'ms',\n })\n : undefined;\n\n // Return wrapped function\n function wrappedFunction(\n this: unknown,\n ...args: TArgs\n ): TReturn | Promise<TReturn> {\n const samplingContext: SamplingContext = {\n operationName: spanName,\n args,\n metadata: {},\n };\n\n const shouldSample = sampler.shouldSample(samplingContext);\n // Read the rate next to the decision that produced it: a windowed sampler\n // can move on to a new rate before the span closes.\n const sampleRate = sampler.sampleRate?.(samplingContext);\n const needsTailSampling = sampler.needsTailSampling?.() ?? false;\n\n // If not sampling and no tail sampling, execute without tracing\n if (!shouldSample && !needsTailSampling) {\n const fn = fnFactory(createDummyCtx());\n return fn.call(this, ...args);\n }\n\n const startTime = performance.now();\n\n const isRootSpan =\n options.startNewRoot || otelTrace.getActiveSpan() === undefined;\n const flushRootTelemetry = createRootTelemetryFlusher(options, isRootSpan);\n\n // Build span options including root and kind\n const spanOptions: import('@opentelemetry/api').SpanOptions = {};\n if (options.startNewRoot) {\n spanOptions.root = true;\n }\n if (options.spanKind !== undefined) {\n spanOptions.kind = options.spanKind;\n }\n\n const parentContext = getActiveContextWithBaggage();\n return tracer.startActiveSpan(\n spanName,\n spanOptions,\n parentContext,\n (span) => {\n // Run within operation context so events can auto-capture operation.name\n return runInOperationContext(spanName, () =>\n runWithTraceContextStorage(() => {\n let shouldKeepSpan = true;\n\n // Store span name for trace context helpers\n setSpanName(span, spanName);\n\n // Only worth recording when the sampler actually dropped events.\n if (sampleRate !== undefined && sampleRate > 1) {\n span.setAttribute(AUTOTEL_SAMPLING_RATE, sampleRate);\n }\n\n // Create trace context for this span using shared utility\n const ctxValue = createTraceContext(span);\n\n // Get the actual function from the factory\n const fn = fnFactory(ctxValue);\n\n // Extract attributes only when actually tracing\n // This avoids expensive preprocessing when sampling rejects the trace\n const argsAttributes: Attributes = {\n ...captureInputAttrs(args, options.captureInput),\n ...(options.attributesFromArgs\n ? options.attributesFromArgs(args)\n : {}),\n } as Attributes;\n\n const handleTailSampling = (\n success: boolean,\n duration: number,\n error?: Error,\n ) => {\n if (needsTailSampling && sampler.shouldKeepTrace) {\n shouldKeepSpan = sampler.shouldKeepTrace(samplingContext, {\n success,\n duration,\n error,\n });\n span.setAttribute(AUTOTEL_SAMPLING_TAIL_KEEP, shouldKeepSpan);\n span.setAttribute(AUTOTEL_SAMPLING_TAIL_EVALUATED, true);\n }\n };\n\n const onSuccess = (result: TReturn) => {\n const duration = performance.now() - startTime;\n\n callCounter?.add(1, {\n operation: spanName,\n status: 'success',\n });\n\n durationHistogram?.record(duration, {\n operation: spanName,\n status: 'success',\n });\n\n const resultAttributes = {\n ...captureOutputAttrs(result, options.captureOutput),\n ...(options.attributesFromResult\n ? options.attributesFromResult(result)\n : {}),\n };\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.setAttributes({\n ...argsAttributes,\n ...resultAttributes,\n 'operation.name': spanName,\n 'code.function': spanName,\n 'operation.duration': duration,\n 'operation.success': true,\n });\n\n handleTailSampling(true, duration);\n\n span.end();\n return result;\n };\n\n const onError = (error: unknown): never => {\n finalizeThrownSpan(error, options.isError, {\n span,\n spanName,\n duration: performance.now() - startTime,\n callCounter,\n durationHistogram,\n handleTailSampling,\n extraAttributes: argsAttributes,\n });\n throw error;\n };\n\n try {\n callCounter?.add(1, {\n operation: spanName,\n status: 'started',\n });\n\n const result = context.with(getActiveContextWithBaggage(), () =>\n fn.call(this, ...args),\n );\n\n if (result instanceof Promise) {\n return result.then(\n async (value) => {\n const completed = onSuccess(value);\n await flushRootTelemetry();\n return completed;\n },\n async (error) => {\n try {\n return onError(error);\n } finally {\n await flushRootTelemetry();\n }\n },\n );\n }\n\n const completed = onSuccess(result);\n void flushRootTelemetry();\n return completed;\n } catch (error) {\n try {\n return onError(error);\n } finally {\n void flushRootTelemetry();\n }\n }\n }),\n );\n },\n );\n }\n\n // Mark as instrumented to prevent double-wrapping\n (wrappedFunction as InstrumentedFlag)[INSTRUMENTED_SYMBOL] = true;\n\n Object.defineProperty(wrappedFunction, 'name', {\n value: variableName || 'trace',\n configurable: true,\n });\n\n return wrappedFunction as WrappedFunction<TArgs, TReturn>;\n}\n\n/**\n * Approach 1: trace() - Zero-ceremony HOF\n *\n * Wrap a plain function with automatic tracing. The function receives its real\n * arguments; no context parameter is injected. Use\n * {@link getActiveTraceContext} inside the function, or use {@link withTracing}\n * for the explicit `(ctx) => (...args) => result` factory form.\n *\n * @example Auto-inferred name - Plain function\n * ```typescript\n * export const createUser = trace(async (data) => {\n * return await db.users.create(data)\n * })\n * // → Traced as \"createUser\"\n * ```\n *\n * @example Ambient context access\n * ```typescript\n * export const createUser = trace(async (data) => {\n * getActiveTraceContext()?.setAttribute('user.id', data.id)\n * return await db.users.create(data)\n * })\n * ```\n *\n * @example Custom name - Plain function\n * ```typescript\n * export const createUser = trace('user.create', async (data) => {\n * return await db.users.create(data)\n * })\n * // → Traced as \"user.create\"\n * ```\n *\n * @example Explicit factory context with withTracing()\n * ```typescript\n * export const createUser = withTracing({ name: 'user.create' })((ctx) => async (data) => {\n * ctx.setAttribute('user.id', data.id)\n * return await db.users.create(data)\n * })\n * ```\n *\n * @example Full options - Plain function\n * ```typescript\n * export const createUser = trace({\n * name: 'user.create',\n * sampler: new AdaptiveSampler(),\n * withMetrics: true\n * }, async (data) => {\n * return await db.users.create(data)\n * })\n * ```\n *\n */\n// Plain-function overloads. `trace()` always wraps a plain function that\n// receives its real arguments; it never injects a context parameter and never\n// inspects the function. Reach the active span via getActiveTraceContext()\n// inside the body. For the explicit `(ctx) => (args) => result` factory form,\n// use withTracing(). `TReturn` captures the return type verbatim, so async\n// functions infer `(...args) => Promise<...>` with no separate overload.\n\n// trace(fn)\nexport function trace<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => TReturn,\n): (...args: TArgs) => TReturn;\n// trace(name, fn)\nexport function trace<TArgs extends unknown[], TReturn>(\n name: string,\n fn: (...args: TArgs) => TReturn,\n): (...args: TArgs) => TReturn;\n// trace(options, fn)\nexport function trace<TArgs extends unknown[], TReturn>(\n options: TracingOptions<TArgs, TReturn>,\n fn: (...args: TArgs) => TReturn,\n): (...args: TArgs) => TReturn;\n// Implementation\nexport function trace<TArgs extends unknown[] = unknown[], TReturn = unknown>(\n fnOrNameOrOptions:\n | ((...args: TArgs) => TReturn)\n | ((...args: TArgs) => Promise<TReturn>)\n | string\n | TracingOptions<TArgs, TReturn>,\n maybeFn?:\n ((...args: TArgs) => TReturn) | ((...args: TArgs) => Promise<TReturn>),\n): WrappedFunction<TArgs, TReturn> {\n // trace(fn) - the function is plain; it receives its real arguments and no\n // context is injected. Reach the active span via getActiveTraceContext().\n if (typeof fnOrNameOrOptions === 'function') {\n return wrapPlainWithTracing(\n fnOrNameOrOptions as (...args: TArgs) => TReturn,\n {} as TracingOptions<TArgs, TReturn>,\n );\n }\n\n // trace(name, fn) or trace(options, fn)\n if (!maybeFn) {\n throw new Error('trace(name|options, fn): fn is required');\n }\n\n const options: TracingOptions<TArgs, TReturn> =\n typeof fnOrNameOrOptions === 'string'\n ? ({ name: fnOrNameOrOptions } as TracingOptions<TArgs, TReturn>)\n : fnOrNameOrOptions;\n\n return wrapPlainWithTracing(maybeFn as (...args: TArgs) => TReturn, options);\n}\n\n/**\n * Approach 2: withTracing() - Middleware-style composable wrapper\n *\n * Returns a HOF that wraps functions with tracing.\n * Perfect for composition and reusable configuration.\n *\n * @example Standard usage\n * ```typescript\n * export const createUser = withTracing({\n * name: 'user.create'\n * })(ctx => async (data) => {\n * ctx.setAttribute('user.id', data.id)\n * return await db.users.create(data)\n * })\n * ```\n *\n * @example Composable\n * ```typescript\n * const tracer = withTracing({ serviceName: 'user' })\n *\n * export const createUser = tracer(ctx => async (data) => { })\n * export const updateUser = tracer(ctx => async (id, data) => { })\n * ```\n *\n * @example With other middleware\n * ```typescript\n * export const createUser = compose(\n * withAuth({ role: 'admin' }),\n * withTracing({ name: 'user.create' }),\n * withRateLimit({ max: 100 })\n * )(ctx => async (data) => { })\n * ```\n */\nexport function withTracing<\n TCfgArgs extends unknown[] = unknown[],\n TCfgReturn = unknown,\n>(options: TracingOptions<TCfgArgs, TCfgReturn> = {}) {\n return <TArgs extends TCfgArgs, TReturn extends TCfgReturn>(\n fnFactory: (\n ctx: TraceContext,\n ) => (...args: TArgs) => TReturn | Promise<TReturn>,\n ): WrappedFunction<TArgs, TReturn> =>\n wrapFactoryWithTracing<TArgs, TReturn>(fnFactory, options);\n}\n\n/**\n * Approach 3: instrument() - Batch auto-instrumentation\n *\n * Instrument an entire module/object at once.\n * Closest to @Instrumented decorator pattern.\n *\n * @example Basic usage\n * ```typescript\n * export default instrument({\n * functions: {\n * createUser: async (data) => { },\n * updateUser: async (id, data) => { },\n * deleteUser: async (id) => { }\n * },\n * serviceName: 'user',\n * sampler: new AdaptiveSampler()\n * })\n * // → Traced as \"user.createUser\", \"user.updateUser\", \"user.deleteUser\"\n * ```\n *\n * @example Per-function overrides\n * ```typescript\n * export default instrument({\n * functions: {\n * createUser: async (data) => { },\n * deleteUser: async (id) => { }\n * },\n * serviceName: 'user',\n * overrides: {\n * deleteUser: {\n * sampler: new AlwaysSampler(),\n * withMetrics: true\n * }\n * }\n * })\n * ```\n *\n * @example Skip functions\n * ```typescript\n * export default instrument({\n * functions: {\n * createUser: async (data) => { },\n * _internal: async () => { }, // Auto-skipped (_-prefix)\n * deleteUser: async (id) => { }\n * },\n * serviceName: 'user',\n * skip: [/^test/, (key) => key.includes('debug')]\n * })\n * ```\n */\nexport function instrument<TFunction extends AnyInstrumentable>(\n options: SingleInstrumentOptions<TFunction>,\n): TFunction;\nexport function instrument<T extends Record<string, AnyInstrumentable>>(\n options: InstrumentOptions<T>,\n): T;\nexport function instrument<\n T extends Record<string, AnyInstrumentable>,\n TFunction extends AnyInstrumentable,\n>(\n options: InstrumentOptions<T> | SingleInstrumentOptions<TFunction>,\n): T | TFunction {\n if (!options || typeof options !== 'object') {\n throw new TypeError(\n 'instrument: expected { key, fn } or { functions: { name: fn } }',\n );\n }\n\n if ('key' in options || 'fn' in options) {\n const { key, fn, ...tracingOptions } =\n options as SingleInstrumentOptions<TFunction>;\n if (typeof key !== 'string' || key.trim() === '') {\n throw new TypeError(\n 'instrument: \"key\" must be a non-empty string in the { key, fn } form',\n );\n }\n if (typeof fn !== 'function') {\n throw new TypeError(\n 'instrument: \"fn\" must be a function in the { key, fn } form',\n );\n }\n return wrapPlainWithTracing(fn, tracingOptions, key) as TFunction;\n }\n\n const { functions, ...tracingOptions } = options as InstrumentOptions<T>;\n if (!functions || typeof functions !== 'object') {\n throw new TypeError(\n 'instrument: expected { key, fn } or { functions: { name: fn } }',\n );\n }\n const instrumented: Partial<T> = {};\n\n for (const key of Object.keys(functions)) {\n const typedKey = key as keyof T;\n const fn = functions[typedKey];\n\n // Skip if not a function or undefined - just pass through the value\n if (!fn || typeof fn !== 'function') {\n instrumented[typedKey] = fn as T[typeof typedKey];\n continue;\n }\n\n // Only instrument own enumerable async functions\n // Check if should skip\n if (shouldSkip(key, fn, tracingOptions.skip)) {\n instrumented[typedKey] = fn as T[typeof typedKey];\n continue;\n }\n\n // Merge base options with per-function overrides\n const fnOptions: TracingOptions = {\n ...tracingOptions,\n ...tracingOptions.overrides?.[key],\n // If no explicit name, use key as function name\n name: tracingOptions.overrides?.[key]?.name,\n };\n\n // Bind function to original object to preserve 'this' context\n // This ensures methods can access state on the original object\n const boundFn = fn.bind(functions);\n\n // Convert plain function to factory pattern for trace()\n // For instrument(), we create a factory that ignores ctx and returns the original function\n const fnFactory = (ctx: TraceContext) => {\n void ctx;\n return boundFn;\n };\n\n // Wrap with tracing (sync or async based on implementation)\n instrumented[typedKey] = wrapFactoryWithTracing(\n fnFactory,\n fnOptions,\n key,\n ) as unknown as T[typeof typedKey];\n }\n\n return instrumented as T;\n}\n\n/**\n * Options for span() function\n */\nexport interface SpanOptions {\n /** Span name */\n name: string;\n /** Attributes to set on the span */\n attributes?: Record<string, string | number | boolean>;\n /** OpenTelemetry span kind */\n spanKind?: import('@opentelemetry/api').SpanKind;\n}\n\n/**\n * Execute a function within a named span\n *\n * Useful for adding tracing to specific code blocks without wrapping\n * the entire function. Supports both synchronous and asynchronous functions.\n *\n * Mirrors `trace()`: pass a span name as the first argument for the common\n * case, or full `SpanOptions` when you need to attach attributes.\n *\n * @example\n * ```typescript\n * // Name shorthand\n * await span('payment.charge', async (span) => {\n * await chargeCustomer(order);\n * })\n *\n * // Full options when attributes are needed\n * await span(\n * { name: 'payment.charge', attributes: { amount: order.total } },\n * async (span) => {\n * await chargeCustomer(order);\n * },\n * )\n *\n * // Sync\n * const total = span('calculateTotal', (span) => {\n * return items.reduce((sum, item) => sum + item.price, 0);\n * })\n * ```\n */\n// Overloads — sync first (more specific match), then async.\n// Each shape is offered with a string name OR a full SpanOptions object so\n// span() aligns with trace()'s argument flexibility.\nexport function span<T = unknown>(name: string, fn: (span: Span) => T): T;\nexport function span<T = unknown>(\n name: string,\n fn: (span: Span) => Promise<T>,\n): Promise<T>;\nexport function span<T = unknown>(\n options: SpanOptions,\n fn: (span: Span) => T,\n): T;\nexport function span<T = unknown>(\n options: SpanOptions,\n fn: (span: Span) => Promise<T>,\n): Promise<T>;\n// Implementation\nexport function span<T = unknown>(\n nameOrOptions: string | SpanOptions,\n fn: (span: Span) => T | Promise<T>,\n): T | Promise<T> {\n const options: SpanOptions =\n typeof nameOrOptions === 'string' ? { name: nameOrOptions } : nameOrOptions;\n const config = getConfig();\n const tracer = config.tracer;\n const { name, attributes, spanKind } = options;\n\n const executeSpan = (span: Span) => {\n // Run within operation context so events can auto-capture operation.name\n return runInOperationContext(name, () => {\n try {\n // Set attributes\n if (attributes) {\n for (const [key, value] of Object.entries(attributes)) {\n span.setAttribute(key, value);\n }\n }\n\n const result = fn(span);\n\n // Check if result is a Promise\n if (result instanceof Promise) {\n return result\n .then((resolved) => {\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n return resolved;\n })\n .catch((error) => {\n const errorMessage =\n error instanceof Error\n ? error.message.slice(0, MAX_ERROR_MESSAGE_LENGTH)\n : String(error).slice(0, MAX_ERROR_MESSAGE_LENGTH);\n\n span.setAttribute('error.message', errorMessage);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: errorMessage,\n });\n\n span.recordException(\n error instanceof Error ? error : new Error(String(error)),\n );\n span.end();\n throw error;\n });\n } else {\n // Synchronous function\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n return result;\n }\n } catch (error) {\n // Synchronous error handling\n const errorMessage =\n error instanceof Error\n ? error.message.slice(0, MAX_ERROR_MESSAGE_LENGTH)\n : String(error).slice(0, MAX_ERROR_MESSAGE_LENGTH);\n\n span.setAttribute('error.message', errorMessage);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: errorMessage,\n });\n\n span.recordException(\n error instanceof Error ? error : new Error(String(error)),\n );\n span.end();\n throw error;\n }\n });\n };\n\n const parentContext = getActiveContextWithBaggage();\n const result = tracer.startActiveSpan(\n name,\n spanKind === undefined ? {} : { kind: spanKind },\n parentContext,\n executeSpan,\n );\n\n // tracer.startActiveSpan might return a Promise even for sync callbacks\n // Check if it's a Promise and handle accordingly\n if (result instanceof Promise) {\n return result;\n }\n\n return result as T;\n}\n\n/**\n * Options for withNewContext() function\n */\nexport interface WithNewContextOptions<T = unknown> {\n /** Function to execute in new root context */\n fn: () => Promise<T>;\n}\n\n/**\n * Execute a function in a new root context (prevents span propagation)\n *\n * Useful when you want to start a completely new trace without\n * parent-child relationships.\n *\n * @example\n * ```typescript\n * async function handleWebhook(payload: WebhookPayload) {\n * // This creates a new root trace, not connected to the HTTP request trace\n * await withNewContext({\n * fn: async () => {\n * await span('webhook.process', async () => {\n * await processWebhookPayload(payload)\n * })\n * }\n * })\n * }\n * ```\n */\nexport async function withNewContext<T = unknown>(\n options: WithNewContextOptions<T>,\n): Promise<T> {\n const { fn } = options;\n const config = getConfig();\n const tracer = config.tracer;\n\n // Start a new root span (breaks trace propagation)\n return tracer.startActiveSpan('root', { root: true }, async (span) => {\n try {\n const result = await fn();\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.recordException(\n error instanceof Error ? error : new Error(String(error)),\n );\n span.setStatus({ code: SpanStatusCode.ERROR });\n throw error;\n } finally {\n span.end();\n }\n });\n}\n\n/**\n * Options for withBaggage() function\n */\nexport interface WithBaggageOptions<T = unknown> {\n /** Baggage entries to set (key-value pairs) */\n baggage: Record<string, string>;\n /** Function to execute with the updated baggage */\n fn: () => T | Promise<T>;\n}\n\n/**\n * Execute a function with updated baggage entries\n *\n * Baggage is immutable in OpenTelemetry, so this helper creates a new context\n * with the specified baggage entries and runs the function within that context.\n * All child spans created within the function will inherit the baggage.\n *\n * @example Setting baggage for downstream services\n * ```typescript\n * import { withTracing, withBaggage } from 'autotel';\n *\n * export const createOrder = withTracing({ name: 'order.create' })((ctx) => async (order: Order) => {\n * // Set baggage that will be propagated to downstream HTTP calls\n * return await withBaggage({\n * baggage: {\n * 'tenant.id': order.tenantId,\n * 'user.id': order.userId,\n * },\n * fn: async () => {\n * // This HTTP call will include the baggage in headers\n * await fetch('/api/charge', {\n * method: 'POST',\n * body: JSON.stringify(order),\n * });\n * },\n * });\n * });\n * ```\n *\n * @example Using with existing baggage\n * ```typescript\n * export const processOrder = withTracing({ name: 'order.process' })((ctx) => async (order: Order) => {\n * // Read existing baggage\n * const tenantId = ctx.getBaggage('tenant.id');\n *\n * // Add additional baggage entries\n * return await withBaggage({\n * baggage: {\n * 'order.id': order.id,\n * 'order.amount': String(order.amount),\n * },\n * fn: async () => {\n * await charge(order);\n * },\n * });\n * });\n * ```\n */\nexport function withBaggage<T = unknown>(\n options: WithBaggageOptions<T>,\n): T | Promise<T> {\n const { baggage: baggageEntries, fn } = options;\n const currentContext = context.active();\n\n // Get existing baggage or create new\n let updatedBaggage =\n propagation.getBaggage(currentContext) ?? propagation.createBaggage();\n\n // Set all baggage entries\n for (const [key, value] of Object.entries(baggageEntries)) {\n updatedBaggage = updatedBaggage.setEntry(key, { value });\n }\n\n // Create new context with updated baggage\n const newContext = propagation.setBaggage(currentContext, updatedBaggage);\n\n // Sync contextStorage so nested traces (via getActiveContextWithBaggage) see the baggage.\n // Use run() instead of enterWith() to properly scope the context changes.\n const ctxStorage = getContextStorage();\n const previousStored = ctxStorage.getStore();\n const baggageEnrichedStored = previousStored\n ? { value: propagation.setBaggage(previousStored.value, updatedBaggage) }\n : { value: newContext };\n\n // Run the function within the new context, scoped properly\n const result = previousStored\n ? ctxStorage.run(baggageEnrichedStored, () => context.with(newContext, fn))\n : context.with(newContext, fn);\n\n if (result instanceof Promise) {\n // For async operations, ensure context is restored after the promise settles\n return result.then(\n (value) => {\n // Restore original context before resolving\n if (previousStored) {\n return ctxStorage.run(previousStored, () => value);\n }\n return value;\n },\n (error) => {\n // Restore original context before rejecting\n if (previousStored) {\n return ctxStorage.run(previousStored, () => {\n throw error;\n });\n }\n throw error;\n },\n );\n }\n\n // Sync function - context automatically restored when scope exits\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"functional-BnDUxnSl.js","names":["getInitConfig","otelTrace","trace"],"sources":["../src/variable-name-inference.ts","../src/functional.ts"],"sourcesContent":["/**\n * Variable Name Inference Utility\n *\n * Attempts to infer variable names from const/export const assignments\n * by analyzing the call stack and parsing source code.\n *\n * This is a best-effort approach with graceful degradation - if inference\n * fails for any reason, it returns undefined without breaking the application.\n */\n\n// namespace imports for browser-bundler compat — see node-require.ts\nimport * as nodeFs from 'node:fs';\nimport * as nodeUrl from 'node:url';\n\ninterface CallLocation {\n file: string;\n line: number;\n column: number;\n}\n\n/**\n * LRU Cache for inferred variable names\n * Key: \"file:line\" (e.g., \"/path/to/file.ts:42\")\n * Value: inferred variable name or undefined\n */\nconst inferenceCache = new Map<string, string | undefined>();\nconst MAX_CACHE_SIZE = 50;\n\n/**\n * Captures the current call stack\n */\nfunction captureStackTrace(): string {\n const originalStackTraceLimit = Error.stackTraceLimit;\n Error.stackTraceLimit = 10; // Only need first few frames\n\n const err = new Error('Stack trace capture');\n const stack = err.stack || '';\n\n Error.stackTraceLimit = originalStackTraceLimit;\n return stack;\n}\n\n/**\n * Parses the stack trace to find where trace() was called\n *\n * Stack trace format (Node.js):\n * at functionName (file:line:column)\n * at file:line:column\n *\n * We skip frames until we find one that's NOT in functional.ts or this file.\n * We also need to skip one additional frame (the trace/span/instrument function itself)\n * to get to the actual user code.\n */\nfunction parseCallLocation(stack: string): CallLocation | undefined {\n const lines = stack.split('\\n');\n let skippedExternalFrame = false;\n\n for (const line of lines) {\n // Skip if line contains this file or functional.ts (internal frames)\n // Be specific about the filename to avoid matching test files\n if (\n line.includes('variable-name-inference.ts') ||\n line.includes('variable-name-inference.js') ||\n line.includes('functional.ts') ||\n line.includes('functional.js')\n ) {\n continue;\n }\n\n // Match various stack trace formats\n // Format 1: at functionName (file:line:column)\n // Format 2: at file:line:column\n const match =\n line.match(/at\\s+(?:.*\\s+)?\\(?([^:]+):(\\d+):(\\d+)\\)?/) ||\n line.match(/^.*?([^:]+):(\\d+):(\\d+)/);\n\n if (match) {\n let filePath = match[1]!.trim();\n\n // Handle file:// URLs (convert to paths)\n if (filePath.startsWith('file://')) {\n try {\n filePath = nodeUrl.fileURLToPath(filePath);\n } catch {\n continue;\n }\n }\n\n // Skip the first external frame (the trace/span function itself)\n // We want the frame where the user CALLS trace(), not inside trace()\n if (!skippedExternalFrame) {\n skippedExternalFrame = true;\n continue;\n }\n\n return {\n file: filePath,\n line: Number.parseInt(match[2]!, 10),\n column: Number.parseInt(match[3]!, 10),\n };\n }\n }\n\n return undefined;\n}\n\n/**\n * Reads a specific line from a source file\n */\nfunction readSourceLine(\n filePath: string,\n lineNumber: number,\n): string | undefined {\n try {\n // Check if we can access the file system (not available in edge runtimes)\n if (typeof nodeFs.readFileSync !== 'function') {\n return undefined;\n }\n\n const content = nodeFs.readFileSync(filePath, 'utf8');\n const lines = content.split('\\n');\n\n // Line numbers are 1-based\n return lines[lineNumber - 1];\n } catch {\n // File doesn't exist, permission denied, or other error\n return undefined;\n }\n}\n\n/**\n * Extracts variable name from source code line using regex patterns\n *\n * Supported patterns:\n * - const varName = anyFunction(\n * - export const varName = anyFunction(\n * - let varName = anyFunction(\n * - var varName = anyFunction(\n *\n * Note: This won't work with destructuring assignments or complex patterns\n */\nfunction extractVariableName(sourceLine: string): string | undefined {\n // Remove leading/trailing whitespace\n const trimmed = sourceLine.trim();\n\n // Pattern: (export)? (const|let|var) varName = anyFunctionCall(\n // We match any function call, not just trace(), to support wrapper functions\n const patterns = [\n // export const varName = anyFunction(\n /export\\s+const\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n // const varName = anyFunction(\n /const\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n // export let varName = anyFunction(\n /export\\s+let\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n // let varName = anyFunction(\n /let\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n // export var varName = anyFunction(\n /export\\s+var\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n // var varName = anyFunction(\n /var\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\\s*=\\s*[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(/,\n ];\n\n for (const pattern of patterns) {\n const match = trimmed.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return undefined;\n}\n\n/**\n * Adds an entry to the cache with LRU eviction\n */\nfunction cacheInference(key: string, value: string | undefined): void {\n // If cache is full, remove oldest entry (first entry in Map)\n if (inferenceCache.size >= MAX_CACHE_SIZE) {\n const firstKey = inferenceCache.keys().next().value;\n if (firstKey) {\n inferenceCache.delete(firstKey);\n }\n }\n\n inferenceCache.set(key, value);\n}\n\n/**\n * Main entry point: Attempts to infer the variable name from the call stack\n *\n * This function:\n * 1. Captures the call stack\n * 2. Parses it to find where trace() was called (file + line)\n * 3. Reads that line from the source file\n * 4. Extracts the variable name using regex\n *\n * Returns undefined if inference fails at any step (graceful degradation).\n * Results are cached to avoid repeated file I/O.\n *\n * @returns The inferred variable name, or undefined if inference failed\n */\nexport function inferVariableNameFromCallStack(): string | undefined {\n try {\n // Capture stack trace\n const stack = captureStackTrace();\n\n // Parse stack to find trace() call location\n const callLocation = parseCallLocation(stack);\n if (!callLocation) {\n return undefined;\n }\n\n // Check cache\n const cacheKey = `${callLocation.file}:${callLocation.line}`;\n if (inferenceCache.has(cacheKey)) {\n return inferenceCache.get(cacheKey);\n }\n\n // Read source line\n const sourceLine = readSourceLine(callLocation.file, callLocation.line);\n if (!sourceLine) {\n return undefined;\n }\n\n // Extract variable name\n const variableName = extractVariableName(sourceLine);\n\n // Cache result (even if undefined, to avoid repeated failed attempts)\n cacheInference(cacheKey, variableName);\n\n return variableName;\n } catch {\n // Graceful degradation - don't break the app if inference fails\n return undefined;\n }\n}\n\n/**\n * Clears the inference cache (useful for testing)\n */\nexport function clearInferenceCache(): void {\n inferenceCache.clear();\n}\n","/**\n * Functional API for non-class code\n *\n * Three approaches for different use cases:\n * 1. trace() - Zero-ceremony HOF for single functions\n * 2. withTracing() - Middleware-style composable wrapper\n * 3. instrument() - Batch auto-instrumentation for modules\n *\n * @example trace() - Single function\n * ```typescript\n * export const createUser = trace(async (data) => {\n * getActiveTraceContext()?.setAttribute('user.id', data.id)\n * return await db.users.create(data)\n * })\n * ```\n *\n * @example withTracing() - Composable middleware\n * ```typescript\n * export const createUser = withTracing({\n * name: 'user.create'\n * })(ctx => async (data) => {\n * ctx.setAttribute('user.id', data.id)\n * return await db.users.create(data)\n * })\n * ```\n *\n * @example instrument() - Batch instrumentation\n * ```typescript\n * export default instrument({\n * createUser: async (data) => { },\n * updateUser: async (id, data) => { }\n * }, { serviceName: 'user' })\n * ```\n */\n\nimport {\n SpanStatusCode,\n trace as otelTrace,\n context,\n propagation,\n type Span,\n type Counter,\n type Histogram,\n type Attributes,\n} from '@opentelemetry/api';\nimport { getConfig } from './config';\nimport { getConfig as getInitConfig, getSdk } from './init';\nimport { getForceFlushableProvider } from './tracer-provider';\nimport {\n type Sampler,\n type SamplingContext,\n AlwaysSampler,\n AUTOTEL_SAMPLING_TAIL_KEEP,\n AUTOTEL_SAMPLING_TAIL_EVALUATED,\n AUTOTEL_SAMPLING_RATE,\n} from './sampling';\nimport { getEventQueue } from './track';\nimport type { TraceContext } from './trace-context';\nimport {\n createTraceContext,\n getActiveContextWithBaggage,\n getContextStorage,\n} from './trace-context';\nimport { setSpanName } from './trace-helpers';\nimport { runInOperationContext } from './operation-context';\nimport { inferVariableNameFromCallStack } from './variable-name-inference';\n\n/**\n * Complete trace context containing trace identifiers and span methods\n *\n * The ctx parameter in trace() functions provides:\n * - traceId, spanId, correlationId from the active span\n * - Span manipulation methods (setAttribute, setAttributes, setStatus, recordException)\n *\n * For custom context, access it directly in your functions (standard OpenTelemetry pattern).\n *\n * @example\n * ```typescript\n * import { trace } from 'autotel'\n *\n * export const createUser = withTracing({})((ctx) => async (data: CreateUserData) => {\n * // Get custom context directly (standard OTel approach)\n * const userId = getCurrentUserId()\n * const tenantId = getCurrentTenant()\n *\n * // Use ctx for span operations and trace IDs\n * ctx.setAttribute('user.id', data.id)\n * ctx.setAttribute('user.tenant', tenantId)\n * console.log(ctx.traceId) // Trace IDs available\n * })\n * ```\n */\nexport type { TraceContext } from './trace-context';\n\nlet unknownSpanNameWarningEmitted = false;\n\ntype WrappedFunction<TArgs extends unknown[], TReturn> = (\n ...args: TArgs\n) => TReturn | Promise<TReturn>;\n\nfunction resolveVariableName(\n named: InstrumentableFunction,\n variableName?: string,\n): string | undefined {\n const suppliedFunctionName = inferFunctionName(named);\n const callStackVariableName = suppliedFunctionName\n ? undefined\n : inferVariableNameFromCallStack();\n return variableName || suppliedFunctionName || callStackVariableName;\n}\n\n/**\n * Wrap an explicit context factory `(ctx) => (...args) => result`.\n * Used by {@link withTracing}; the input is a factory by contract, so there is\n * no plain-vs-factory detection. The factory is never invoked at construction\n * time — only when the wrapper is called.\n */\nfunction wrapFactoryWithTracing<TArgs extends unknown[], TReturn>(\n factory: (\n ctx: TraceContext,\n ) => (...args: TArgs) => TReturn | Promise<TReturn>,\n options: TracingOptions<TArgs, TReturn>,\n variableName?: string,\n): WrappedFunction<TArgs, TReturn> {\n const effectiveVariableName = resolveVariableName(\n factory as InstrumentableFunction,\n variableName,\n );\n return wrapWithTracingSync(\n factory,\n options,\n effectiveVariableName,\n ) as WrappedFunction<TArgs, TReturn>;\n}\n\n/**\n * Wrap a plain function `(...args) => result`. Used by {@link trace} and\n * {@link instrument}: the function receives its real arguments and no context\n * is injected. Reach the active span via {@link getActiveTraceContext} inside\n * the body (or any helper it calls).\n */\nfunction wrapPlainWithTracing<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => TReturn | Promise<TReturn>,\n options: TracingOptions<TArgs, TReturn>,\n variableName?: string,\n): WrappedFunction<TArgs, TReturn> {\n const effectiveVariableName = resolveVariableName(\n fn as InstrumentableFunction,\n variableName,\n );\n const factory = (_ctx: TraceContext) => fn;\n return wrapWithTracingSync(\n factory,\n options,\n effectiveVariableName,\n ) as WrappedFunction<TArgs, TReturn>;\n}\n\n/**\n * Common options for functional tracing\n */\nexport interface TracingOptions<\n TArgs extends unknown[] = unknown[],\n TReturn = unknown,\n> {\n /**\n * Span name (highest priority)\n * If provided, this is used as the span name\n */\n name?: string;\n\n /**\n * Service name (used to compose final span name)\n * If name not provided, span name becomes: ${serviceName}.${functionName}\n */\n serviceName?: string;\n\n /**\n * Sampling strategy\n * @default AlwaysSampler\n */\n sampler?: Sampler;\n\n /**\n * Enable metrics collection (counter, histogram)\n * @default false\n */\n withMetrics?: boolean;\n\n /**\n * Extract attributes from function arguments\n */\n attributesFromArgs?: (args: TArgs) => Record<string, unknown>;\n\n /**\n * Extract attributes from function result\n */\n attributesFromResult?: (result: TReturn) => Record<string, unknown>;\n\n /**\n * Capture the function arguments onto the span as `autotel.input`\n * (JSON, truncated). One arg is captured directly; multiple are captured as\n * an array. Off by default — opt in per call. Tools (visualizers, devtools)\n * read this alongside `ai.toolCall.args` to show function I/O uniformly.\n * Avoid on args with secrets/PII, or pair with a redacting processor.\n */\n captureInput?: boolean;\n\n /**\n * Capture the function return value onto the span as `autotel.output`\n * (JSON, truncated). Off by default. Same caveats as {@link captureInput}.\n */\n captureOutput?: boolean;\n\n /**\n * Start a new root span instead of creating a child\n * Useful for serverless entry points\n * @default false\n */\n startNewRoot?: boolean;\n\n /**\n * Flush events queue when span ends\n * Only flushes on root spans (to avoid excessive flushing)\n * @default true\n */\n flushOnRootSpanEnd?: boolean;\n\n /**\n * Span kind for semantic convention compliance\n * Used for messaging (PRODUCER/CONSUMER), HTTP (CLIENT/SERVER), etc.\n * @default SpanKind.INTERNAL\n */\n spanKind?: import('@opentelemetry/api').SpanKind;\n\n /**\n * Classify a thrown value as a real error. Return `false` to treat the throw\n * as expected control flow: the span is marked OK, no exception is recorded,\n * and the value is rethrown untouched. Use this for framework control-flow\n * signals that propagate via `throw` but are not failures — e.g. TanStack\n * Router / Next.js `redirect()` and `notFound()`.\n * @default every throw is treated as an error\n */\n isError?: (error: unknown) => boolean;\n}\n\n/**\n * Options for instrument() batch instrumentation\n */\nexport interface InstrumentOptions<\n T extends Record<string, AnyInstrumentable> = Record<\n string,\n AnyInstrumentable\n >,\n> extends TracingOptions {\n /** Object whose function properties should be instrumented */\n functions: T;\n /**\n * Per-function configuration overrides\n */\n overrides?: Record<string, Partial<TracingOptions>>;\n\n /**\n * Functions to skip (won't be instrumented)\n * Supports:\n * - String keys: 'functionName'\n * - RegExp: /^_internal/\n * - Predicate: (key, fn) => boolean\n *\n * By default, functions starting with _ are skipped\n */\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n skip?: (string | RegExp | ((key: string, fn: Function) => boolean))[];\n}\n\n/**\n * Options for instrumenting one function with an explicit stable key.\n */\nexport interface SingleInstrumentOptions<\n TFunction extends AnyInstrumentable = AnyInstrumentable,\n> extends TracingOptions {\n /** Stable function key used for span naming */\n key: string;\n /** Function to instrument */\n fn: TFunction;\n}\n\n// Maximum error message length to prevent span bloat\nconst MAX_ERROR_MESSAGE_LENGTH = 500;\n\nfunction createDummyCtx<\n TBaggage extends Record<string, unknown> | undefined = undefined,\n>(): TraceContext<TBaggage> {\n // `recordException` / `addEvent` are no-op shims kept for the same\n // compatibility window as `createTraceContext` (see trace-context.ts).\n return {\n traceId: '',\n spanId: '',\n correlationId: '',\n setAttribute: () => {},\n setAttributes: () => {},\n setStatus: () => {},\n recordException: () => {},\n addEvent: () => {},\n addLink: () => {},\n addLinks: () => {},\n updateName: () => {},\n isRecording: () => false,\n getBaggage: () => {},\n setBaggage: () => '',\n deleteBaggage: () => {},\n getAllBaggage: () => new Map(),\n } as unknown as TraceContext<TBaggage>;\n}\n\n/** Attribute keys for opt-in function I/O capture (see TracingOptions). */\nconst AUTOTEL_INPUT_ATTR = 'autotel.input';\nconst AUTOTEL_OUTPUT_ATTR = 'autotel.output';\nconst CAPTURE_MAX_CHARS = 4096;\n\n/** JSON-serialize a captured value, defensively (truncate, swallow cycles). */\nfunction serializeCapture(value: unknown): string | undefined {\n if (value === undefined) return undefined;\n try {\n const json = typeof value === 'string' ? value : JSON.stringify(value);\n if (json === undefined) return undefined;\n return json.length > CAPTURE_MAX_CHARS\n ? `${json.slice(0, CAPTURE_MAX_CHARS)}…[truncated]`\n : json;\n } catch {\n return undefined;\n }\n}\n\n/** `autotel.input` from args (single arg captured directly, else the array). */\nfunction captureInputAttrs(\n args: unknown[],\n enabled?: boolean,\n): Record<string, unknown> {\n if (!enabled) return {};\n const s = serializeCapture(args.length === 1 ? args[0] : args);\n return s === undefined ? {} : { [AUTOTEL_INPUT_ATTR]: s };\n}\n\n/** `autotel.output` from the return value. */\nfunction captureOutputAttrs(\n result: unknown,\n enabled?: boolean,\n): Record<string, unknown> {\n if (!enabled) return {};\n const s = serializeCapture(result);\n return s === undefined ? {} : { [AUTOTEL_OUTPUT_ATTR]: s };\n}\n\n// Symbol to prevent double-instrumentation (idempotency flag)\nconst INSTRUMENTED_SYMBOL = Symbol.for('autotel.functional.instrumented');\n\ntype InstrumentedFlag = {\n [INSTRUMENTED_SYMBOL]?: true;\n};\n\nfunction hasInstrumentationFlag(value: unknown): value is InstrumentedFlag {\n return (\n (typeof value === 'function' || typeof value === 'object') &&\n value !== null &&\n Boolean((value as InstrumentedFlag)[INSTRUMENTED_SYMBOL])\n );\n}\n\n/**\n * Truncate error message to prevent span bloat\n */\nfunction truncateErrorMessage(message: string): string {\n if (message.length <= MAX_ERROR_MESSAGE_LENGTH) {\n return message;\n }\n return `${message.slice(0, MAX_ERROR_MESSAGE_LENGTH)}... (truncated)`;\n}\n\n/** Per-invocation state the terminal span handlers close over. */\ninterface SpanFinalizeContext {\n span: Span;\n spanName: string;\n duration: number;\n callCounter?: Counter;\n durationHistogram?: Histogram;\n handleTailSampling: (\n success: boolean,\n duration: number,\n error?: Error,\n ) => void;\n /** Extra attributes to merge (e.g. captured args); absent on immediate-exec paths. */\n extraAttributes?: Attributes;\n}\n\n/**\n * Terminal handling for a value thrown by a traced function. Shared by all four\n * `trace()` execution paths (immediate + wrapper, sync + async) so the outcome\n * rules live in exactly one place. Ends the span; the caller flushes (await/void)\n * and rethrows.\n *\n * If `isError` classifies the throw as expected control flow — e.g. a framework\n * `redirect()` / `notFound()` signal — it is recorded as a success outcome with\n * an OK status and no exception. Otherwise it is recorded as an error.\n */\nfunction finalizeThrownSpan(\n error: unknown,\n isError: ((error: unknown) => boolean) | undefined,\n ctx: SpanFinalizeContext,\n): void {\n const {\n span,\n spanName,\n duration,\n callCounter,\n durationHistogram,\n handleTailSampling,\n extraAttributes,\n } = ctx;\n\n const baseAttributes: Attributes = {\n ...extraAttributes,\n 'operation.name': spanName,\n 'code.function': spanName,\n 'operation.duration': duration,\n };\n\n if (isError && !isError(error)) {\n callCounter?.add(1, { operation: spanName, status: 'success' });\n durationHistogram?.record(duration, {\n operation: spanName,\n status: 'success',\n });\n span.setStatus({ code: SpanStatusCode.OK });\n span.setAttributes({ ...baseAttributes, 'operation.success': true });\n handleTailSampling(true, duration);\n span.end();\n return;\n }\n\n callCounter?.add(1, { operation: spanName, status: 'error' });\n durationHistogram?.record(duration, { operation: spanName, status: 'error' });\n\n const truncatedMessage = truncateErrorMessage(\n error instanceof Error ? error.message : 'Unknown error',\n );\n\n span.setStatus({ code: SpanStatusCode.ERROR, message: truncatedMessage });\n span.setAttributes({\n ...baseAttributes,\n 'operation.success': false,\n error: true,\n 'exception.type': error instanceof Error ? error.constructor.name : 'Error',\n 'exception.message': truncatedMessage,\n });\n if (error instanceof Error && error.stack) {\n span.setAttribute(\n 'exception.stack',\n error.stack.slice(0, MAX_ERROR_MESSAGE_LENGTH),\n );\n }\n const thrown = error instanceof Error ? error : new Error(String(error));\n span.recordException(thrown);\n // Samplers read result.error, so hand them a real Error rather than\n // whatever the code threw.\n handleTailSampling(false, duration, thrown);\n span.end();\n}\n\ntype InstrumentableFunction<\n TArgs extends unknown[] = unknown[],\n TReturn = unknown,\n> = ((...args: TArgs) => TReturn | Promise<TReturn>) & {\n displayName?: string;\n name?: string;\n};\n\n/**\n * Constraint alias for `instrument()` and friends. `never[]` parameters make\n * every concretely-typed function (e.g. `(name: string) => Promise<User>`)\n * satisfy the constraint under `strictFunctionTypes` without resorting to\n * `any`. Use ONLY in constraint positions — the concrete `T` is still\n * inferred from the actual argument, so call-site argument and return types\n * are fully preserved.\n */\ntype AnyInstrumentable = ((...args: never[]) => unknown) & {\n displayName?: string;\n name?: string;\n};\n\n/**\n * Try to infer function name from function properties\n * Checks for displayName, name, or other metadata that might be set\n */\nfunction inferFunctionName<\n TArgs extends unknown[] = unknown[],\n TReturn = unknown,\n>(fn: InstrumentableFunction<TArgs, TReturn>): string | undefined {\n // Check for displayName property (sometimes set by bundlers)\n const displayName = (fn as { displayName?: string }).displayName;\n if (displayName) {\n return displayName;\n }\n\n // Check function.name (works for named functions and modern arrow function assignment)\n // Note: Empty string is falsy, so this handles both undefined and ''\n if (fn.name && fn.name !== 'anonymous' && fn.name !== '') {\n return fn.name;\n }\n\n // Try to extract name from function source (for function declarations)\n const source = Function.prototype.toString.call(fn);\n const match = source.match(/function\\s+([^(\\s]+)/);\n if (match && match[1] && match[1] !== 'anonymous') {\n return match[1];\n }\n\n return undefined;\n}\n\n/**\n * Determine span name using priority:\n * 1. Explicit name option\n * 2. serviceName + functionName\n * 3. Inferred from function/variable name (including stack trace fallback)\n * 4. Fallback to 'unknown'\n */\nfunction getSpanName<TArgs extends unknown[], TReturn>(\n options: TracingOptions<TArgs, TReturn>,\n fn: InstrumentableFunction<TArgs, TReturn>,\n variableName?: string,\n): string {\n // 1. Explicit name\n if (options.name) {\n return options.name;\n }\n\n // 2. Try variable name, function name, or function properties\n let fnName = variableName || inferFunctionName(fn);\n\n // Default to 'anonymous' if still no name\n fnName = fnName || 'anonymous';\n\n // 2. serviceName + functionName\n if (options.serviceName) {\n return `${options.serviceName}.${fnName}`;\n }\n\n // 3. Inferred from function name\n if (fnName && fnName !== 'anonymous') {\n return fnName;\n }\n\n // 4. Fallback\n const initConfig = getInitConfig();\n if (\n typeof process !== 'undefined' &&\n process.env.NODE_ENV !== 'production' &&\n !unknownSpanNameWarningEmitted &&\n initConfig?.logger?.warn\n ) {\n unknownSpanNameWarningEmitted = true;\n initConfig.logger.warn(\n {},\n '[autotel] Span name resolved to \"unknown\". Pass an explicit name, for example trace(\"operation.name\", fn).',\n );\n }\n return 'unknown';\n}\n\n/**\n * Check if function should be skipped\n */\nfunction shouldSkip(\n key: string,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n fn: Function,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n skip?: (string | RegExp | ((key: string, fn: Function) => boolean))[],\n): boolean {\n // Default: skip functions starting with _\n if (key.startsWith('_')) {\n return true;\n }\n\n if (!skip || skip.length === 0) {\n return false;\n }\n\n for (const rule of skip) {\n if (typeof rule === 'string' && key === rule) {\n return true;\n } else if (rule instanceof RegExp && rule.test(key)) {\n return true;\n } else if (typeof rule === 'function' && rule(key, fn)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Get current trace context value (internal helper)\n *\n * Returns base context (trace IDs) + span methods from the active span.\n */\nfunction getCtxValue<\n TBaggage extends Record<string, unknown> | undefined = undefined,\n>(): TraceContext<TBaggage> | null {\n const activeSpan = otelTrace.getActiveSpan();\n if (!activeSpan) return null;\n\n // Use shared utility to create trace context\n return createTraceContext<TBaggage>(activeSpan);\n}\n\n/**\n * Get the autotel {@link TraceContext} for the currently active span.\n *\n * This is the ambient accessor for the functional API: instead of threading a\n * `ctx` parameter through a factory, call this inside any traced function (or a\n * helper it calls) to reach `setAttribute`, `setUser`, `getBaggage`, and the\n * rest of the context surface. Returns `undefined` when no span is active.\n *\n * @example\n * ```typescript\n * const getUser = trace('getUser', async (id: string) => {\n * getActiveTraceContext()?.setAttribute('user.id', id);\n * return db.users.find(id);\n * });\n * ```\n *\n * @see getActiveSpan for the raw OpenTelemetry span\n * @see getRequestLogger which reads the active context when called with no args\n */\nexport function getActiveTraceContext<\n TBaggage extends Record<string, unknown> | undefined = undefined,\n>(): TraceContext<TBaggage> | undefined {\n return getCtxValue<TBaggage>() ?? undefined;\n}\n\n/**\n * Context object that lazily evaluates the active span on property access\n *\n * Access trace context directly without function call syntax.\n *\n * @example\n * ```typescript\n * import { trace, ctx } from 'autotel'\n *\n * export const createUser = trace(async (data) => {\n * // Direct property access - no function call!\n * if (ctx.traceId) {\n * ctx.setAttribute('user.id', data.id)\n * console.log('Trace:', ctx.traceId)\n * }\n * })\n * ```\n */\nexport const ctx = new Proxy({} as TraceContext, {\n get(_target, prop) {\n const ctxValue = getCtxValue();\n if (!ctxValue) {\n return;\n }\n return ctxValue[prop as keyof typeof ctxValue];\n },\n\n has(_target, prop) {\n const ctxValue = getCtxValue();\n if (!ctxValue) {\n return false;\n }\n return prop in ctxValue;\n },\n\n ownKeys() {\n const ctxValue = getCtxValue();\n if (!ctxValue) {\n return [];\n }\n return Object.keys(ctxValue);\n },\n\n getOwnPropertyDescriptor(_target, prop) {\n const ctxValue = getCtxValue();\n if (!ctxValue) {\n return;\n }\n return Object.getOwnPropertyDescriptor(ctxValue, prop);\n },\n});\n\n/**\n * Build the root-operation flush policy once and reuse it for wrapped and\n * immediate execution. Async operations await this function; sync operations\n * trigger it without blocking.\n */\nfunction createRootTelemetryFlusher(\n options: Pick<TracingOptions, 'flushOnRootSpanEnd'>,\n isRootSpan: boolean,\n): () => Promise<void> {\n const initConfig = getInitConfig();\n const shouldFlush =\n options.flushOnRootSpanEnd ?? initConfig?.flushOnRootSpanEnd ?? true;\n const shouldFlushSpans = initConfig?.forceFlushOnShutdown ?? false;\n\n return async () => {\n if (!shouldFlush || !isRootSpan) return;\n\n try {\n const queue = getEventQueue();\n if (queue && queue.size() > 0) {\n await queue.flush();\n }\n\n if (shouldFlushSpans) {\n const tracerProvider = getForceFlushableProvider(getSdk());\n await tracerProvider?.forceFlush();\n }\n } catch (error) {\n const logger = getInitConfig()?.logger;\n logger?.error?.(\n { err: error instanceof Error ? error : undefined },\n `[autotel] Auto-flush failed${error instanceof Error ? '' : `: ${String(error)}`}`,\n );\n }\n };\n}\n\n/**\n * Give every root operation its own baggage context without replacing a\n * caller's existing scope. AsyncLocalStorage keeps the scope alive until an\n * async result settles and restores the previous store afterwards.\n */\nfunction runWithTraceContextStorage<TResult>(fn: () => TResult): TResult {\n const storage = getContextStorage();\n if (storage.getStore()) return fn();\n return storage.run({ value: context.active() }, fn);\n}\n\n/**\n * Core tracing wrapper for sync functions (internal implementation)\n */\nfunction wrapWithTracingSync<TArgs extends unknown[], TReturn>(\n fnFactory: (\n ctx: TraceContext,\n ) => (...args: TArgs) => TReturn | Promise<TReturn>,\n options: TracingOptions<TArgs, TReturn>,\n variableName?: string,\n): WrappedFunction<TArgs, TReturn> {\n // Idempotency check: if already instrumented, return as-is\n if (hasInstrumentationFlag(fnFactory)) {\n // If already instrumented, we need to extract the original factory\n // For now, we'll just proceed - this edge case is handled by the wrapped function check\n }\n\n const config = getConfig();\n const tracer = config.tracer;\n const meter = config.meter;\n // Annotate as Sampler so the optional hooks stay visible. Inference would\n // narrow to AlwaysSampler and hide them behind `in` checks.\n const sampler: Sampler = options.sampler || new AlwaysSampler();\n\n const spanName = getSpanName(\n options,\n fnFactory as unknown as InstrumentableFunction<TArgs, TReturn>,\n variableName,\n );\n\n // Metrics setup (if enabled)\n const callCounter = options.withMetrics\n ? meter.createCounter(`${spanName}.calls`, {\n description: `Call count for ${spanName}`,\n unit: '1',\n })\n : undefined;\n\n const durationHistogram = options.withMetrics\n ? meter.createHistogram(`${spanName}.duration`, {\n description: `Duration for ${spanName}`,\n unit: 'ms',\n })\n : undefined;\n\n // Return wrapped function\n function wrappedFunction(\n this: unknown,\n ...args: TArgs\n ): TReturn | Promise<TReturn> {\n const samplingContext: SamplingContext = {\n operationName: spanName,\n args,\n metadata: {},\n };\n\n const shouldSample = sampler.shouldSample(samplingContext);\n // Read the rate next to the decision that produced it: a windowed sampler\n // can move on to a new rate before the span closes.\n const sampleRate = sampler.sampleRate?.(samplingContext);\n const needsTailSampling = sampler.needsTailSampling?.() ?? false;\n\n // If not sampling and no tail sampling, execute without tracing\n if (!shouldSample && !needsTailSampling) {\n const fn = fnFactory(createDummyCtx());\n return fn.call(this, ...args);\n }\n\n const startTime = performance.now();\n\n const isRootSpan =\n options.startNewRoot || otelTrace.getActiveSpan() === undefined;\n const flushRootTelemetry = createRootTelemetryFlusher(options, isRootSpan);\n\n // Build span options including root and kind\n const spanOptions: import('@opentelemetry/api').SpanOptions = {};\n if (options.startNewRoot) {\n spanOptions.root = true;\n }\n if (options.spanKind !== undefined) {\n spanOptions.kind = options.spanKind;\n }\n\n const parentContext = getActiveContextWithBaggage();\n return tracer.startActiveSpan(\n spanName,\n spanOptions,\n parentContext,\n (span) => {\n // Run within operation context so events can auto-capture operation.name\n return runInOperationContext(spanName, () =>\n runWithTraceContextStorage(() => {\n let shouldKeepSpan = true;\n\n // Store span name for trace context helpers\n setSpanName(span, spanName);\n\n // Only worth recording when the sampler actually dropped events.\n if (sampleRate !== undefined && sampleRate > 1) {\n span.setAttribute(AUTOTEL_SAMPLING_RATE, sampleRate);\n }\n\n // Create trace context for this span using shared utility\n const ctxValue = createTraceContext(span);\n\n // Get the actual function from the factory\n const fn = fnFactory(ctxValue);\n\n // Extract attributes only when actually tracing\n // This avoids expensive preprocessing when sampling rejects the trace\n const argsAttributes: Attributes = {\n ...captureInputAttrs(args, options.captureInput),\n ...(options.attributesFromArgs\n ? options.attributesFromArgs(args)\n : {}),\n } as Attributes;\n\n const handleTailSampling = (\n success: boolean,\n duration: number,\n error?: Error,\n ) => {\n if (needsTailSampling && sampler.shouldKeepTrace) {\n shouldKeepSpan = sampler.shouldKeepTrace(samplingContext, {\n success,\n duration,\n error,\n });\n span.setAttribute(AUTOTEL_SAMPLING_TAIL_KEEP, shouldKeepSpan);\n span.setAttribute(AUTOTEL_SAMPLING_TAIL_EVALUATED, true);\n }\n };\n\n const onSuccess = (result: TReturn) => {\n const duration = performance.now() - startTime;\n\n callCounter?.add(1, {\n operation: spanName,\n status: 'success',\n });\n\n durationHistogram?.record(duration, {\n operation: spanName,\n status: 'success',\n });\n\n const resultAttributes = {\n ...captureOutputAttrs(result, options.captureOutput),\n ...(options.attributesFromResult\n ? options.attributesFromResult(result)\n : {}),\n };\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.setAttributes({\n ...argsAttributes,\n ...resultAttributes,\n 'operation.name': spanName,\n 'code.function': spanName,\n 'operation.duration': duration,\n 'operation.success': true,\n });\n\n handleTailSampling(true, duration);\n\n span.end();\n return result;\n };\n\n const onError = (error: unknown): never => {\n finalizeThrownSpan(error, options.isError, {\n span,\n spanName,\n duration: performance.now() - startTime,\n callCounter,\n durationHistogram,\n handleTailSampling,\n extraAttributes: argsAttributes,\n });\n throw error;\n };\n\n try {\n callCounter?.add(1, {\n operation: spanName,\n status: 'started',\n });\n\n const result = context.with(getActiveContextWithBaggage(), () =>\n fn.call(this, ...args),\n );\n\n if (result instanceof Promise) {\n return result.then(\n async (value) => {\n const completed = onSuccess(value);\n await flushRootTelemetry();\n return completed;\n },\n async (error) => {\n try {\n return onError(error);\n } finally {\n await flushRootTelemetry();\n }\n },\n );\n }\n\n const completed = onSuccess(result);\n void flushRootTelemetry();\n return completed;\n } catch (error) {\n try {\n return onError(error);\n } finally {\n void flushRootTelemetry();\n }\n }\n }),\n );\n },\n );\n }\n\n // Mark as instrumented to prevent double-wrapping\n (wrappedFunction as InstrumentedFlag)[INSTRUMENTED_SYMBOL] = true;\n\n Object.defineProperty(wrappedFunction, 'name', {\n value: variableName || 'trace',\n configurable: true,\n });\n\n return wrappedFunction as WrappedFunction<TArgs, TReturn>;\n}\n\n/**\n * Approach 1: trace() - Zero-ceremony HOF\n *\n * Wrap a plain function with automatic tracing. The function receives its real\n * arguments; no context parameter is injected. Use\n * {@link getActiveTraceContext} inside the function, or use {@link withTracing}\n * for the explicit `(ctx) => (...args) => result` factory form.\n *\n * @example Auto-inferred name - Plain function\n * ```typescript\n * export const createUser = trace(async (data) => {\n * return await db.users.create(data)\n * })\n * // → Traced as \"createUser\"\n * ```\n *\n * @example Ambient context access\n * ```typescript\n * export const createUser = trace(async (data) => {\n * getActiveTraceContext()?.setAttribute('user.id', data.id)\n * return await db.users.create(data)\n * })\n * ```\n *\n * @example Custom name - Plain function\n * ```typescript\n * export const createUser = trace('user.create', async (data) => {\n * return await db.users.create(data)\n * })\n * // → Traced as \"user.create\"\n * ```\n *\n * @example Explicit factory context with withTracing()\n * ```typescript\n * export const createUser = withTracing({ name: 'user.create' })((ctx) => async (data) => {\n * ctx.setAttribute('user.id', data.id)\n * return await db.users.create(data)\n * })\n * ```\n *\n * @example Full options - Plain function\n * ```typescript\n * export const createUser = trace({\n * name: 'user.create',\n * sampler: new AdaptiveSampler(),\n * withMetrics: true\n * }, async (data) => {\n * return await db.users.create(data)\n * })\n * ```\n *\n */\n// Plain-function overloads. `trace()` always wraps a plain function that\n// receives its real arguments; it never injects a context parameter and never\n// inspects the function. Reach the active span via getActiveTraceContext()\n// inside the body. For the explicit `(ctx) => (args) => result` factory form,\n// use withTracing(). `TReturn` captures the return type verbatim, so async\n// functions infer `(...args) => Promise<...>` with no separate overload.\n\n// trace(fn)\nexport function trace<TArgs extends unknown[], TReturn>(\n fn: (...args: TArgs) => TReturn,\n): (...args: TArgs) => TReturn;\n// trace(name, fn)\nexport function trace<TArgs extends unknown[], TReturn>(\n name: string,\n fn: (...args: TArgs) => TReturn,\n): (...args: TArgs) => TReturn;\n// trace(options, fn)\nexport function trace<TArgs extends unknown[], TReturn>(\n options: TracingOptions<TArgs, TReturn>,\n fn: (...args: TArgs) => TReturn,\n): (...args: TArgs) => TReturn;\n// Implementation\nexport function trace<TArgs extends unknown[] = unknown[], TReturn = unknown>(\n fnOrNameOrOptions:\n | ((...args: TArgs) => TReturn)\n | ((...args: TArgs) => Promise<TReturn>)\n | string\n | TracingOptions<TArgs, TReturn>,\n maybeFn?:\n ((...args: TArgs) => TReturn) | ((...args: TArgs) => Promise<TReturn>),\n): WrappedFunction<TArgs, TReturn> {\n // trace(fn) - the function is plain; it receives its real arguments and no\n // context is injected. Reach the active span via getActiveTraceContext().\n if (typeof fnOrNameOrOptions === 'function') {\n return wrapPlainWithTracing(\n fnOrNameOrOptions as (...args: TArgs) => TReturn,\n {} as TracingOptions<TArgs, TReturn>,\n );\n }\n\n // trace(name, fn) or trace(options, fn)\n if (!maybeFn) {\n throw new Error('trace(name|options, fn): fn is required');\n }\n\n const options: TracingOptions<TArgs, TReturn> =\n typeof fnOrNameOrOptions === 'string'\n ? ({ name: fnOrNameOrOptions } as TracingOptions<TArgs, TReturn>)\n : fnOrNameOrOptions;\n\n return wrapPlainWithTracing(maybeFn as (...args: TArgs) => TReturn, options);\n}\n\n/**\n * Approach 2: withTracing() - Middleware-style composable wrapper\n *\n * Returns a HOF that wraps functions with tracing.\n * Perfect for composition and reusable configuration.\n *\n * @example Standard usage\n * ```typescript\n * export const createUser = withTracing({\n * name: 'user.create'\n * })(ctx => async (data) => {\n * ctx.setAttribute('user.id', data.id)\n * return await db.users.create(data)\n * })\n * ```\n *\n * @example Composable\n * ```typescript\n * const tracer = withTracing({ serviceName: 'user' })\n *\n * export const createUser = tracer(ctx => async (data) => { })\n * export const updateUser = tracer(ctx => async (id, data) => { })\n * ```\n *\n * @example With other middleware\n * ```typescript\n * export const createUser = compose(\n * withAuth({ role: 'admin' }),\n * withTracing({ name: 'user.create' }),\n * withRateLimit({ max: 100 })\n * )(ctx => async (data) => { })\n * ```\n */\nexport function withTracing<\n TCfgArgs extends unknown[] = unknown[],\n TCfgReturn = unknown,\n>(options: TracingOptions<TCfgArgs, TCfgReturn> = {}) {\n return <TArgs extends TCfgArgs, TReturn extends TCfgReturn>(\n fnFactory: (\n ctx: TraceContext,\n ) => (...args: TArgs) => TReturn | Promise<TReturn>,\n ): WrappedFunction<TArgs, TReturn> =>\n wrapFactoryWithTracing<TArgs, TReturn>(fnFactory, options);\n}\n\n/**\n * Approach 3: instrument() - Batch auto-instrumentation\n *\n * Instrument an entire module/object at once.\n * Closest to @Instrumented decorator pattern.\n *\n * @example Basic usage\n * ```typescript\n * export default instrument({\n * functions: {\n * createUser: async (data) => { },\n * updateUser: async (id, data) => { },\n * deleteUser: async (id) => { }\n * },\n * serviceName: 'user',\n * sampler: new AdaptiveSampler()\n * })\n * // → Traced as \"user.createUser\", \"user.updateUser\", \"user.deleteUser\"\n * ```\n *\n * @example Per-function overrides\n * ```typescript\n * export default instrument({\n * functions: {\n * createUser: async (data) => { },\n * deleteUser: async (id) => { }\n * },\n * serviceName: 'user',\n * overrides: {\n * deleteUser: {\n * sampler: new AlwaysSampler(),\n * withMetrics: true\n * }\n * }\n * })\n * ```\n *\n * @example Skip functions\n * ```typescript\n * export default instrument({\n * functions: {\n * createUser: async (data) => { },\n * _internal: async () => { }, // Auto-skipped (_-prefix)\n * deleteUser: async (id) => { }\n * },\n * serviceName: 'user',\n * skip: [/^test/, (key) => key.includes('debug')]\n * })\n * ```\n */\nexport function instrument<TFunction extends AnyInstrumentable>(\n options: SingleInstrumentOptions<TFunction>,\n): TFunction;\nexport function instrument<T extends Record<string, AnyInstrumentable>>(\n options: InstrumentOptions<T>,\n): T;\nexport function instrument<\n T extends Record<string, AnyInstrumentable>,\n TFunction extends AnyInstrumentable,\n>(\n options: InstrumentOptions<T> | SingleInstrumentOptions<TFunction>,\n): T | TFunction {\n if (!options || typeof options !== 'object') {\n throw new TypeError(\n 'instrument: expected { key, fn } or { functions: { name: fn } }',\n );\n }\n\n if ('key' in options || 'fn' in options) {\n const { key, fn, ...tracingOptions } =\n options as SingleInstrumentOptions<TFunction>;\n if (typeof key !== 'string' || key.trim() === '') {\n throw new TypeError(\n 'instrument: \"key\" must be a non-empty string in the { key, fn } form',\n );\n }\n if (typeof fn !== 'function') {\n throw new TypeError(\n 'instrument: \"fn\" must be a function in the { key, fn } form',\n );\n }\n return wrapPlainWithTracing(fn, tracingOptions, key) as TFunction;\n }\n\n const { functions, ...tracingOptions } = options as InstrumentOptions<T>;\n if (!functions || typeof functions !== 'object') {\n throw new TypeError(\n 'instrument: expected { key, fn } or { functions: { name: fn } }',\n );\n }\n const instrumented: Partial<T> = {};\n\n for (const key of Object.keys(functions)) {\n const typedKey = key as keyof T;\n const fn = functions[typedKey];\n\n // Skip if not a function or undefined - just pass through the value\n if (!fn || typeof fn !== 'function') {\n instrumented[typedKey] = fn as T[typeof typedKey];\n continue;\n }\n\n // Only instrument own enumerable async functions\n // Check if should skip\n if (shouldSkip(key, fn, tracingOptions.skip)) {\n instrumented[typedKey] = fn as T[typeof typedKey];\n continue;\n }\n\n // Merge base options with per-function overrides\n const fnOptions: TracingOptions = {\n ...tracingOptions,\n ...tracingOptions.overrides?.[key],\n // If no explicit name, use key as function name\n name: tracingOptions.overrides?.[key]?.name,\n };\n\n // Bind function to original object to preserve 'this' context\n // This ensures methods can access state on the original object\n const boundFn = fn.bind(functions);\n\n // Convert plain function to factory pattern for trace()\n // For instrument(), we create a factory that ignores ctx and returns the original function\n const fnFactory = (ctx: TraceContext) => {\n void ctx;\n return boundFn;\n };\n\n // Wrap with tracing (sync or async based on implementation)\n instrumented[typedKey] = wrapFactoryWithTracing(\n fnFactory,\n fnOptions,\n key,\n ) as unknown as T[typeof typedKey];\n }\n\n return instrumented as T;\n}\n\n/**\n * Options for span() function\n */\nexport interface SpanOptions {\n /** Span name */\n name: string;\n /** Attributes to set on the span */\n attributes?: Record<string, string | number | boolean>;\n /** OpenTelemetry span kind */\n spanKind?: import('@opentelemetry/api').SpanKind;\n}\n\n/**\n * Execute a function within a named span\n *\n * Useful for adding tracing to specific code blocks without wrapping\n * the entire function. Supports both synchronous and asynchronous functions.\n *\n * Mirrors `trace()`: pass a span name as the first argument for the common\n * case, or full `SpanOptions` when you need to attach attributes.\n *\n * @example\n * ```typescript\n * // Name shorthand\n * await span('payment.charge', async (span) => {\n * await chargeCustomer(order);\n * })\n *\n * // Full options when attributes are needed\n * await span(\n * { name: 'payment.charge', attributes: { amount: order.total } },\n * async (span) => {\n * await chargeCustomer(order);\n * },\n * )\n *\n * // Sync\n * const total = span('calculateTotal', (span) => {\n * return items.reduce((sum, item) => sum + item.price, 0);\n * })\n * ```\n */\n// Overloads — sync first (more specific match), then async.\n// Each shape is offered with a string name OR a full SpanOptions object so\n// span() aligns with trace()'s argument flexibility.\nexport function span<T = unknown>(name: string, fn: (span: Span) => T): T;\nexport function span<T = unknown>(\n name: string,\n fn: (span: Span) => Promise<T>,\n): Promise<T>;\nexport function span<T = unknown>(\n options: SpanOptions,\n fn: (span: Span) => T,\n): T;\nexport function span<T = unknown>(\n options: SpanOptions,\n fn: (span: Span) => Promise<T>,\n): Promise<T>;\n// Implementation\nexport function span<T = unknown>(\n nameOrOptions: string | SpanOptions,\n fn: (span: Span) => T | Promise<T>,\n): T | Promise<T> {\n const options: SpanOptions =\n typeof nameOrOptions === 'string' ? { name: nameOrOptions } : nameOrOptions;\n const config = getConfig();\n const tracer = config.tracer;\n const { name, attributes, spanKind } = options;\n\n const executeSpan = (span: Span) => {\n // Run within operation context so events can auto-capture operation.name\n return runInOperationContext(name, () => {\n try {\n // Set attributes\n if (attributes) {\n for (const [key, value] of Object.entries(attributes)) {\n span.setAttribute(key, value);\n }\n }\n\n const result = fn(span);\n\n // Check if result is a Promise\n if (result instanceof Promise) {\n return result\n .then((resolved) => {\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n return resolved;\n })\n .catch((error) => {\n const errorMessage =\n error instanceof Error\n ? error.message.slice(0, MAX_ERROR_MESSAGE_LENGTH)\n : String(error).slice(0, MAX_ERROR_MESSAGE_LENGTH);\n\n span.setAttribute('error.message', errorMessage);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: errorMessage,\n });\n\n span.recordException(\n error instanceof Error ? error : new Error(String(error)),\n );\n span.end();\n throw error;\n });\n } else {\n // Synchronous function\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n return result;\n }\n } catch (error) {\n // Synchronous error handling\n const errorMessage =\n error instanceof Error\n ? error.message.slice(0, MAX_ERROR_MESSAGE_LENGTH)\n : String(error).slice(0, MAX_ERROR_MESSAGE_LENGTH);\n\n span.setAttribute('error.message', errorMessage);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: errorMessage,\n });\n\n span.recordException(\n error instanceof Error ? error : new Error(String(error)),\n );\n span.end();\n throw error;\n }\n });\n };\n\n const parentContext = getActiveContextWithBaggage();\n const result = tracer.startActiveSpan(\n name,\n spanKind === undefined ? {} : { kind: spanKind },\n parentContext,\n executeSpan,\n );\n\n // tracer.startActiveSpan might return a Promise even for sync callbacks\n // Check if it's a Promise and handle accordingly\n if (result instanceof Promise) {\n return result;\n }\n\n return result as T;\n}\n\n/**\n * Options for withNewContext() function\n */\nexport interface WithNewContextOptions<T = unknown> {\n /** Function to execute in new root context */\n fn: () => Promise<T>;\n}\n\n/**\n * Execute a function in a new root context (prevents span propagation)\n *\n * Useful when you want to start a completely new trace without\n * parent-child relationships.\n *\n * @example\n * ```typescript\n * async function handleWebhook(payload: WebhookPayload) {\n * // This creates a new root trace, not connected to the HTTP request trace\n * await withNewContext({\n * fn: async () => {\n * await span('webhook.process', async () => {\n * await processWebhookPayload(payload)\n * })\n * }\n * })\n * }\n * ```\n */\nexport async function withNewContext<T = unknown>(\n options: WithNewContextOptions<T>,\n): Promise<T> {\n const { fn } = options;\n const config = getConfig();\n const tracer = config.tracer;\n\n // Start a new root span (breaks trace propagation)\n return tracer.startActiveSpan('root', { root: true }, async (span) => {\n try {\n const result = await fn();\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.recordException(\n error instanceof Error ? error : new Error(String(error)),\n );\n span.setStatus({ code: SpanStatusCode.ERROR });\n throw error;\n } finally {\n span.end();\n }\n });\n}\n\n/**\n * Options for withBaggage() function\n */\nexport interface WithBaggageOptions<T = unknown> {\n /** Baggage entries to set (key-value pairs) */\n baggage: Record<string, string>;\n /** Function to execute with the updated baggage */\n fn: () => T | Promise<T>;\n}\n\n/**\n * Execute a function with updated baggage entries\n *\n * Baggage is immutable in OpenTelemetry, so this helper creates a new context\n * with the specified baggage entries and runs the function within that context.\n * All child spans created within the function will inherit the baggage.\n *\n * @example Setting baggage for downstream services\n * ```typescript\n * import { withTracing, withBaggage } from 'autotel';\n *\n * export const createOrder = withTracing({ name: 'order.create' })((ctx) => async (order: Order) => {\n * // Set baggage that will be propagated to downstream HTTP calls\n * return await withBaggage({\n * baggage: {\n * 'tenant.id': order.tenantId,\n * 'user.id': order.userId,\n * },\n * fn: async () => {\n * // This HTTP call will include the baggage in headers\n * await fetch('/api/charge', {\n * method: 'POST',\n * body: JSON.stringify(order),\n * });\n * },\n * });\n * });\n * ```\n *\n * @example Using with existing baggage\n * ```typescript\n * export const processOrder = withTracing({ name: 'order.process' })((ctx) => async (order: Order) => {\n * // Read existing baggage\n * const tenantId = ctx.getBaggage('tenant.id');\n *\n * // Add additional baggage entries\n * return await withBaggage({\n * baggage: {\n * 'order.id': order.id,\n * 'order.amount': String(order.amount),\n * },\n * fn: async () => {\n * await charge(order);\n * },\n * });\n * });\n * ```\n */\nexport function withBaggage<T = unknown>(\n options: WithBaggageOptions<T>,\n): T | Promise<T> {\n const { baggage: baggageEntries, fn } = options;\n const currentContext = context.active();\n\n // Get existing baggage or create new\n let updatedBaggage =\n propagation.getBaggage(currentContext) ?? propagation.createBaggage();\n\n // Set all baggage entries\n for (const [key, value] of Object.entries(baggageEntries)) {\n updatedBaggage = updatedBaggage.setEntry(key, { value });\n }\n\n // Create new context with updated baggage\n const newContext = propagation.setBaggage(currentContext, updatedBaggage);\n\n // Sync contextStorage so nested traces (via getActiveContextWithBaggage) see the baggage.\n // Use run() instead of enterWith() to properly scope the context changes.\n const ctxStorage = getContextStorage();\n const previousStored = ctxStorage.getStore();\n const baggageEnrichedStored = previousStored\n ? { value: propagation.setBaggage(previousStored.value, updatedBaggage) }\n : { value: newContext };\n\n // Run the function within the new context, scoped properly\n const result = previousStored\n ? ctxStorage.run(baggageEnrichedStored, () => context.with(newContext, fn))\n : context.with(newContext, fn);\n\n if (result instanceof Promise) {\n // For async operations, ensure context is restored after the promise settles\n return result.then(\n (value) => {\n // Restore original context before resolving\n if (previousStored) {\n return ctxStorage.run(previousStored, () => value);\n }\n return value;\n },\n (error) => {\n // Restore original context before rejecting\n if (previousStored) {\n return ctxStorage.run(previousStored, () => {\n throw error;\n });\n }\n throw error;\n },\n );\n }\n\n // Sync function - context automatically restored when scope exits\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -2,10 +2,8 @@ const require_rolldown_runtime = require('./rolldown-runtime-C_NdSu1c.cjs');
|
|
|
2
2
|
const require_tracer_provider = require('./tracer-provider.cjs');
|
|
3
3
|
const require_config = require('./config.cjs');
|
|
4
4
|
const require_sampling = require('./sampling.cjs');
|
|
5
|
-
const require_init = require('./init-
|
|
6
|
-
const require_track = require('./track-BI6dmZ2X.cjs');
|
|
5
|
+
const require_init = require('./init-C3RApHKJ.cjs');
|
|
7
6
|
const require_trace_helpers = require('./trace-helpers.cjs');
|
|
8
|
-
const require_operation_context = require('./operation-context-hzKbTKnt.cjs');
|
|
9
7
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
10
8
|
let node_fs = require("node:fs");
|
|
11
9
|
node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
|
|
@@ -384,7 +382,7 @@ function shouldSkip(key, fn, skip) {
|
|
|
384
382
|
function getCtxValue() {
|
|
385
383
|
const activeSpan = _opentelemetry_api.trace.getActiveSpan();
|
|
386
384
|
if (!activeSpan) return null;
|
|
387
|
-
return
|
|
385
|
+
return require_init.createTraceContext(activeSpan);
|
|
388
386
|
}
|
|
389
387
|
/**
|
|
390
388
|
* Get the autotel {@link TraceContext} for the currently active span.
|
|
@@ -460,7 +458,7 @@ function createRootTelemetryFlusher(options, isRootSpan) {
|
|
|
460
458
|
return async () => {
|
|
461
459
|
if (!shouldFlush || !isRootSpan) return;
|
|
462
460
|
try {
|
|
463
|
-
const queue =
|
|
461
|
+
const queue = require_init.getEventQueue();
|
|
464
462
|
if (queue && queue.size() > 0) await queue.flush();
|
|
465
463
|
if (shouldFlushSpans) await require_tracer_provider.getForceFlushableProvider(require_init.getSdk())?.forceFlush();
|
|
466
464
|
} catch (error) {
|
|
@@ -474,7 +472,7 @@ function createRootTelemetryFlusher(options, isRootSpan) {
|
|
|
474
472
|
* async result settles and restores the previous store afterwards.
|
|
475
473
|
*/
|
|
476
474
|
function runWithTraceContextStorage(fn) {
|
|
477
|
-
const storage =
|
|
475
|
+
const storage = require_init.getContextStorage();
|
|
478
476
|
if (storage.getStore()) return fn();
|
|
479
477
|
return storage.run({ value: _opentelemetry_api.context.active() }, fn);
|
|
480
478
|
}
|
|
@@ -511,13 +509,13 @@ function wrapWithTracingSync(fnFactory, options, variableName) {
|
|
|
511
509
|
const spanOptions = {};
|
|
512
510
|
if (options.startNewRoot) spanOptions.root = true;
|
|
513
511
|
if (options.spanKind !== void 0) spanOptions.kind = options.spanKind;
|
|
514
|
-
const parentContext =
|
|
512
|
+
const parentContext = require_init.getActiveContextWithBaggage();
|
|
515
513
|
return tracer.startActiveSpan(spanName, spanOptions, parentContext, (span) => {
|
|
516
|
-
return
|
|
514
|
+
return require_init.runInOperationContext(spanName, () => runWithTraceContextStorage(() => {
|
|
517
515
|
let shouldKeepSpan = true;
|
|
518
516
|
require_trace_helpers.setSpanName(span, spanName);
|
|
519
517
|
if (sampleRate !== void 0 && sampleRate > 1) span.setAttribute(require_sampling.AUTOTEL_SAMPLING_RATE, sampleRate);
|
|
520
|
-
const fn = fnFactory(
|
|
518
|
+
const fn = fnFactory(require_init.createTraceContext(span));
|
|
521
519
|
const argsAttributes = {
|
|
522
520
|
...captureInputAttrs(args, options.captureInput),
|
|
523
521
|
...options.attributesFromArgs ? options.attributesFromArgs(args) : {}
|
|
@@ -577,7 +575,7 @@ function wrapWithTracingSync(fnFactory, options, variableName) {
|
|
|
577
575
|
operation: spanName,
|
|
578
576
|
status: "started"
|
|
579
577
|
});
|
|
580
|
-
const result = _opentelemetry_api.context.with(
|
|
578
|
+
const result = _opentelemetry_api.context.with(require_init.getActiveContextWithBaggage(), () => fn.call(this, ...args));
|
|
581
579
|
if (result instanceof Promise) return result.then(async (value) => {
|
|
582
580
|
const completed = onSuccess(value);
|
|
583
581
|
await flushRootTelemetry();
|
|
@@ -690,7 +688,7 @@ function span(nameOrOptions, fn) {
|
|
|
690
688
|
const tracer = require_config.getConfig().tracer;
|
|
691
689
|
const { name, attributes, spanKind } = options;
|
|
692
690
|
const executeSpan = (span) => {
|
|
693
|
-
return
|
|
691
|
+
return require_init.runInOperationContext(name, () => {
|
|
694
692
|
try {
|
|
695
693
|
if (attributes) for (const [key, value] of Object.entries(attributes)) span.setAttribute(key, value);
|
|
696
694
|
const result = fn(span);
|
|
@@ -727,7 +725,7 @@ function span(nameOrOptions, fn) {
|
|
|
727
725
|
}
|
|
728
726
|
});
|
|
729
727
|
};
|
|
730
|
-
const parentContext =
|
|
728
|
+
const parentContext = require_init.getActiveContextWithBaggage();
|
|
731
729
|
const result = tracer.startActiveSpan(name, spanKind === void 0 ? {} : { kind: spanKind }, parentContext, executeSpan);
|
|
732
730
|
if (result instanceof Promise) return result;
|
|
733
731
|
return result;
|
|
@@ -822,7 +820,7 @@ function withBaggage(options) {
|
|
|
822
820
|
let updatedBaggage = _opentelemetry_api.propagation.getBaggage(currentContext) ?? _opentelemetry_api.propagation.createBaggage();
|
|
823
821
|
for (const [key, value] of Object.entries(baggageEntries)) updatedBaggage = updatedBaggage.setEntry(key, { value });
|
|
824
822
|
const newContext = _opentelemetry_api.propagation.setBaggage(currentContext, updatedBaggage);
|
|
825
|
-
const ctxStorage =
|
|
823
|
+
const ctxStorage = require_init.getContextStorage();
|
|
826
824
|
const previousStored = ctxStorage.getStore();
|
|
827
825
|
const baggageEnrichedStored = previousStored ? { value: _opentelemetry_api.propagation.setBaggage(previousStored.value, updatedBaggage) } : { value: newContext };
|
|
828
826
|
const result = previousStored ? ctxStorage.run(baggageEnrichedStored, () => _opentelemetry_api.context.with(newContext, fn)) : _opentelemetry_api.context.with(newContext, fn);
|
|
@@ -887,4 +885,4 @@ Object.defineProperty(exports, 'withTracing', {
|
|
|
887
885
|
return withTracing;
|
|
888
886
|
}
|
|
889
887
|
});
|
|
890
|
-
//# sourceMappingURL=functional-
|
|
888
|
+
//# sourceMappingURL=functional-DcLBuCPz.cjs.map
|