autotel-edge 3.16.13 → 3.16.15

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.
Files changed (45) hide show
  1. package/dist/config-0FktBGyj.js +290 -0
  2. package/dist/config-0FktBGyj.js.map +1 -0
  3. package/dist/events.d.ts +42 -43
  4. package/dist/events.d.ts.map +1 -0
  5. package/dist/events.js +144 -137
  6. package/dist/events.js.map +1 -1
  7. package/dist/execution-logger-BWlya70r.d.ts +137 -0
  8. package/dist/execution-logger-BWlya70r.d.ts.map +1 -0
  9. package/dist/execution-logger-CoxSsBmU.js +247 -0
  10. package/dist/execution-logger-CoxSsBmU.js.map +1 -0
  11. package/dist/index.d.ts +192 -276
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +930 -1060
  14. package/dist/index.js.map +1 -1
  15. package/dist/logger.d.ts +122 -136
  16. package/dist/logger.d.ts.map +1 -0
  17. package/dist/logger.js +783 -774
  18. package/dist/logger.js.map +1 -1
  19. package/dist/parse-error.d.ts +12 -10
  20. package/dist/parse-error.d.ts.map +1 -0
  21. package/dist/parse-error.js +55 -2
  22. package/dist/parse-error.js.map +1 -1
  23. package/dist/sampling.d.ts +51 -76
  24. package/dist/sampling.d.ts.map +1 -0
  25. package/dist/sampling.js +155 -90
  26. package/dist/sampling.js.map +1 -1
  27. package/dist/testing.d.ts +1 -2
  28. package/dist/testing.js +1 -3
  29. package/dist/types-HCbsjZzp.d.ts +214 -0
  30. package/dist/types-HCbsjZzp.d.ts.map +1 -0
  31. package/package.json +6 -6
  32. package/src/core/buffer.ts +4 -3
  33. package/src/core/provider.context.test.ts +55 -0
  34. package/src/core/provider.ts +18 -1
  35. package/binding.gyp +0 -9
  36. package/dist/chunk-AL7ZD64M.js +0 -291
  37. package/dist/chunk-AL7ZD64M.js.map +0 -1
  38. package/dist/chunk-INQQQVXN.js +0 -310
  39. package/dist/chunk-INQQQVXN.js.map +0 -1
  40. package/dist/chunk-M7Z4P5MC.js +0 -64
  41. package/dist/chunk-M7Z4P5MC.js.map +0 -1
  42. package/dist/execution-logger-77TRRoWn.d.ts +0 -84
  43. package/dist/testing.js.map +0 -1
  44. package/dist/types-uulICZo7.d.ts +0 -216
  45. package/index.js +0 -1
package/dist/index.js CHANGED
@@ -1,1152 +1,1022 @@
1
- export { OTLPExporter, createInitialiser, getActiveConfig, parseConfig, setConfig } from './chunk-INQQQVXN.js';
2
- import { setSpanName, createTraceContext } from './chunk-AL7ZD64M.js';
3
- export { getExecutionLogger } from './chunk-AL7ZD64M.js';
4
- export { parseError } from './chunk-M7Z4P5MC.js';
5
- import { sanitizeAttributes, isAttributeValue, isTimeInput, hrTimeDuration } from '@opentelemetry/core';
6
- import { SEMATTRS_EXCEPTION_MESSAGE, SEMATTRS_EXCEPTION_TYPE, SEMATTRS_EXCEPTION_STACKTRACE } from '@opentelemetry/semantic-conventions';
7
- import { trace, context, ROOT_CONTEXT, SpanStatusCode } from '@opentelemetry/api';
8
- export { context, propagation } from '@opentelemetry/api';
9
- import { RandomIdGenerator, SamplingDecision } from '@opentelemetry/sdk-trace-base';
10
- import { AsyncLocalStorage } from 'async_hooks';
11
- import { EventEmitter } from 'events';
12
- import { Buffer } from 'buffer';
13
- export { Buffer } from 'buffer';
1
+ import { a as OTLPExporter, i as setConfig, n as getActiveConfig, r as parseConfig, t as createInitialiser } from "./config-0FktBGyj.js";
2
+ import { n as createTraceContext, r as setSpanName, t as getExecutionLogger } from "./execution-logger-CoxSsBmU.js";
3
+ import { parseError } from "./parse-error.js";
4
+ import { hrTimeDuration, isAttributeValue, isTimeInput, sanitizeAttributes } from "@opentelemetry/core";
5
+ import { SEMATTRS_EXCEPTION_MESSAGE, SEMATTRS_EXCEPTION_STACKTRACE, SEMATTRS_EXCEPTION_TYPE } from "@opentelemetry/semantic-conventions";
6
+ import { ROOT_CONTEXT, SpanStatusCode, context, context as context$1, propagation, trace as trace$1 } from "@opentelemetry/api";
7
+ import { RandomIdGenerator, SamplingDecision } from "@opentelemetry/sdk-trace-base";
8
+ import { AsyncLocalStorage } from "node:async_hooks";
9
+ import { EventEmitter } from "node:events";
10
+ import { Buffer } from "node:buffer";
14
11
 
12
+ //#region src/core/span.ts
15
13
  function transformExceptionAttributes(exception) {
16
- const attributes = {};
17
- if (typeof exception === "string") {
18
- attributes[SEMATTRS_EXCEPTION_MESSAGE] = exception;
19
- } else {
20
- if (exception.code) {
21
- attributes[SEMATTRS_EXCEPTION_TYPE] = exception.code.toString();
22
- } else if (exception.name) {
23
- attributes[SEMATTRS_EXCEPTION_TYPE] = exception.name;
24
- }
25
- if (exception.message) {
26
- attributes[SEMATTRS_EXCEPTION_MESSAGE] = exception.message;
27
- }
28
- if (exception.stack) {
29
- attributes[SEMATTRS_EXCEPTION_STACKTRACE] = exception.stack;
30
- }
31
- }
32
- return attributes;
14
+ const attributes = {};
15
+ if (typeof exception === "string") attributes[SEMATTRS_EXCEPTION_MESSAGE] = exception;
16
+ else {
17
+ if (exception.code) attributes[SEMATTRS_EXCEPTION_TYPE] = exception.code.toString();
18
+ else if (exception.name) attributes[SEMATTRS_EXCEPTION_TYPE] = exception.name;
19
+ if (exception.message) attributes[SEMATTRS_EXCEPTION_MESSAGE] = exception.message;
20
+ if (exception.stack) attributes[SEMATTRS_EXCEPTION_STACKTRACE] = exception.stack;
21
+ }
22
+ return attributes;
33
23
  }
34
24
  function millisToHr(millis) {
35
- return [Math.trunc(millis / 1e3), millis % 1e3 * 1e6];
25
+ return [Math.trunc(millis / 1e3), millis % 1e3 * 1e6];
36
26
  }
37
27
  function getHrTime(input) {
38
- const now = Date.now();
39
- if (!input) {
40
- return millisToHr(now);
41
- } else if (input instanceof Date) {
42
- return millisToHr(input.getTime());
43
- } else if (typeof input === "number") {
44
- return millisToHr(input);
45
- } else if (Array.isArray(input)) {
46
- return input;
47
- }
48
- const v = input;
49
- throw new Error(`unreachable value: ${JSON.stringify(v)}`);
28
+ const now = Date.now();
29
+ if (!input) return millisToHr(now);
30
+ else if (input instanceof Date) return millisToHr(input.getTime());
31
+ else if (typeof input === "number") return millisToHr(input);
32
+ else if (Array.isArray(input)) return input;
33
+ throw new Error(`unreachable value: ${JSON.stringify(input)}`);
50
34
  }
51
35
  function isAttributeKey(key) {
52
- return typeof key === "string" && key.length > 0;
36
+ return typeof key === "string" && key.length > 0;
53
37
  }
38
+ /**
39
+ * Lightweight Span implementation for edge runtimes
40
+ */
54
41
  var SpanImpl = class {
55
- name;
56
- _spanContext;
57
- onEnd;
58
- parentSpanId;
59
- parentSpanContext;
60
- kind;
61
- attributes;
62
- status = {
63
- code: 0
64
- // SpanStatusCode.UNSET
65
- };
66
- endTime = [0, 0];
67
- _duration = [0, 0];
68
- startTime;
69
- events = [];
70
- links;
71
- resource;
72
- instrumentationScope = {
73
- name: "autotel-edge"
74
- };
75
- _ended = false;
76
- _droppedAttributesCount = 0;
77
- _droppedEventsCount = 0;
78
- _droppedLinksCount = 0;
79
- constructor(init) {
80
- this.name = init.name;
81
- this._spanContext = init.spanContext;
82
- this.parentSpanId = init.parentSpanId;
83
- this.parentSpanContext = init.parentSpanContext;
84
- this.kind = init.spanKind || 0;
85
- this.attributes = sanitizeAttributes(init.attributes);
86
- this.startTime = getHrTime(init.startTime);
87
- this.links = init.links || [];
88
- this.resource = init.resource;
89
- this.onEnd = init.onEnd;
90
- }
91
- addLink(link) {
92
- this.links.push(link);
93
- return this;
94
- }
95
- addLinks(links) {
96
- this.links.push(...links);
97
- return this;
98
- }
99
- spanContext() {
100
- return this._spanContext;
101
- }
102
- setAttribute(key, value) {
103
- if (isAttributeKey(key) && isAttributeValue(value)) {
104
- this.attributes[key] = value;
105
- }
106
- return this;
107
- }
108
- setAttributes(attributes) {
109
- for (const [key, value] of Object.entries(attributes)) {
110
- this.setAttribute(key, value);
111
- }
112
- return this;
113
- }
114
- addEvent(name, attributesOrStartTime, startTime) {
115
- if (isTimeInput(attributesOrStartTime)) {
116
- startTime = attributesOrStartTime;
117
- attributesOrStartTime = void 0;
118
- }
119
- const attributes = sanitizeAttributes(attributesOrStartTime);
120
- const time = getHrTime(startTime);
121
- this.events.push({ name, attributes, time });
122
- return this;
123
- }
124
- setStatus(status) {
125
- this.status = status;
126
- return this;
127
- }
128
- updateName(name) {
129
- this.name = name;
130
- return this;
131
- }
132
- end(endTime) {
133
- if (this._ended) {
134
- return;
135
- }
136
- this._ended = true;
137
- this.endTime = getHrTime(endTime);
138
- this._duration = hrTimeDuration(this.startTime, this.endTime);
139
- this.onEnd(this);
140
- }
141
- isRecording() {
142
- return !this._ended;
143
- }
144
- recordException(exception, time) {
145
- const attributes = transformExceptionAttributes(exception);
146
- this.addEvent("exception", attributes, time);
147
- }
148
- get duration() {
149
- return this._duration;
150
- }
151
- get ended() {
152
- return this._ended;
153
- }
154
- get droppedAttributesCount() {
155
- return this._droppedAttributesCount;
156
- }
157
- get droppedEventsCount() {
158
- return this._droppedEventsCount;
159
- }
160
- get droppedLinksCount() {
161
- return this._droppedLinksCount;
162
- }
42
+ name;
43
+ _spanContext;
44
+ onEnd;
45
+ parentSpanId;
46
+ parentSpanContext;
47
+ kind;
48
+ attributes;
49
+ status = { code: 0 };
50
+ endTime = [0, 0];
51
+ _duration = [0, 0];
52
+ startTime;
53
+ events = [];
54
+ links;
55
+ resource;
56
+ instrumentationScope = { name: "autotel-edge" };
57
+ _ended = false;
58
+ _droppedAttributesCount = 0;
59
+ _droppedEventsCount = 0;
60
+ _droppedLinksCount = 0;
61
+ constructor(init) {
62
+ this.name = init.name;
63
+ this._spanContext = init.spanContext;
64
+ this.parentSpanId = init.parentSpanId;
65
+ this.parentSpanContext = init.parentSpanContext;
66
+ this.kind = init.spanKind || 0;
67
+ this.attributes = sanitizeAttributes(init.attributes);
68
+ this.startTime = getHrTime(init.startTime);
69
+ this.links = init.links || [];
70
+ this.resource = init.resource;
71
+ this.onEnd = init.onEnd;
72
+ }
73
+ addLink(link) {
74
+ this.links.push(link);
75
+ return this;
76
+ }
77
+ addLinks(links) {
78
+ this.links.push(...links);
79
+ return this;
80
+ }
81
+ spanContext() {
82
+ return this._spanContext;
83
+ }
84
+ setAttribute(key, value) {
85
+ if (isAttributeKey(key) && isAttributeValue(value)) this.attributes[key] = value;
86
+ return this;
87
+ }
88
+ setAttributes(attributes) {
89
+ for (const [key, value] of Object.entries(attributes)) this.setAttribute(key, value);
90
+ return this;
91
+ }
92
+ addEvent(name, attributesOrStartTime, startTime) {
93
+ if (isTimeInput(attributesOrStartTime)) {
94
+ startTime = attributesOrStartTime;
95
+ attributesOrStartTime = void 0;
96
+ }
97
+ const attributes = sanitizeAttributes(attributesOrStartTime);
98
+ const time = getHrTime(startTime);
99
+ this.events.push({
100
+ name,
101
+ attributes,
102
+ time
103
+ });
104
+ return this;
105
+ }
106
+ setStatus(status) {
107
+ this.status = status;
108
+ return this;
109
+ }
110
+ updateName(name) {
111
+ this.name = name;
112
+ return this;
113
+ }
114
+ end(endTime) {
115
+ if (this._ended) return;
116
+ this._ended = true;
117
+ this.endTime = getHrTime(endTime);
118
+ this._duration = hrTimeDuration(this.startTime, this.endTime);
119
+ this.onEnd(this);
120
+ }
121
+ isRecording() {
122
+ return !this._ended;
123
+ }
124
+ recordException(exception, time) {
125
+ const attributes = transformExceptionAttributes(exception);
126
+ this.addEvent("exception", attributes, time);
127
+ }
128
+ get duration() {
129
+ return this._duration;
130
+ }
131
+ get ended() {
132
+ return this._ended;
133
+ }
134
+ get droppedAttributesCount() {
135
+ return this._droppedAttributesCount;
136
+ }
137
+ get droppedEventsCount() {
138
+ return this._droppedEventsCount;
139
+ }
140
+ get droppedLinksCount() {
141
+ return this._droppedLinksCount;
142
+ }
163
143
  };
164
- var NewTraceFlags = {
165
- RANDOM_TRACE_ID_SET: 2};
166
- var idGenerator = new RandomIdGenerator();
167
- var withNextSpanAttributes;
144
+
145
+ //#endregion
146
+ //#region src/core/tracer.ts
147
+ const NewTraceFlags = {
148
+ RANDOM_TRACE_ID_SET: 2,
149
+ RANDOM_TRACE_ID_UNSET: 0
150
+ };
151
+ const idGenerator = new RandomIdGenerator();
152
+ let withNextSpanAttributes;
168
153
  function getFlagAt(flagSequence, position) {
169
- return (flagSequence >> position - 1 & 1) * position;
154
+ return (flagSequence >> position - 1 & 1) * position;
170
155
  }
156
+ /**
157
+ * WorkerTracer - Lightweight tracer for edge environments
158
+ */
171
159
  var WorkerTracer = class {
172
- spanProcessors;
173
- resource;
174
- headSampler;
175
- // Will be set via setHeadSampler
176
- constructor(spanProcessors, resource) {
177
- this.spanProcessors = spanProcessors;
178
- this.resource = resource;
179
- }
180
- /**
181
- * Set the head sampler (called from config)
182
- */
183
- setHeadSampler(sampler) {
184
- this.headSampler = sampler;
185
- }
186
- /**
187
- * Force flush spans for a specific trace
188
- */
189
- async forceFlush(traceId) {
190
- const promises = this.spanProcessors.map(async (spanProcessor) => {
191
- await spanProcessor.forceFlush(traceId);
192
- });
193
- await Promise.allSettled(promises);
194
- }
195
- /**
196
- * Add extra resource attributes
197
- */
198
- addToResource(extra) {
199
- this.resource.merge(extra);
200
- }
201
- /**
202
- * Start a new span
203
- */
204
- startSpan(name, options = {}, context2 = context.active()) {
205
- if (options.root) {
206
- context2 = trace.deleteSpan(context2);
207
- }
208
- if (!this.headSampler) {
209
- throw new Error(
210
- "Head sampler not configured. This is a bug in the instrumentation logic"
211
- );
212
- }
213
- const parentSpanContext = trace.getSpan(context2)?.spanContext();
214
- const { traceId, randomTraceFlag } = getTraceInfo(parentSpanContext);
215
- const spanKind = options.kind || 0;
216
- const sanitisedAttrs = sanitizeAttributes(options.attributes);
217
- const optionsWithSampler = options;
218
- const sampler = optionsWithSampler.sampler || this.headSampler;
219
- const samplingDecision = sampler.shouldSample(
220
- context2,
221
- traceId,
222
- name,
223
- spanKind,
224
- sanitisedAttrs,
225
- []
226
- );
227
- const { decision, traceState, attributes: attrs } = samplingDecision;
228
- const attributes = Object.assign(
229
- {},
230
- options.attributes,
231
- attrs,
232
- withNextSpanAttributes
233
- );
234
- withNextSpanAttributes = {};
235
- const spanId = idGenerator.generateSpanId();
236
- const parentSpanId = parentSpanContext?.spanId;
237
- const sampleFlag = decision === SamplingDecision.RECORD_AND_SAMPLED ? 1 : 0;
238
- const traceFlags = sampleFlag + randomTraceFlag;
239
- const spanContext = { traceId, spanId, traceFlags, traceState };
240
- const span2 = new SpanImpl({
241
- attributes: sanitizeAttributes(attributes),
242
- name,
243
- onEnd: (span3) => {
244
- for (const sp of this.spanProcessors) {
245
- sp.onEnd(span3);
246
- }
247
- },
248
- resource: this.resource,
249
- spanContext,
250
- parentSpanContext,
251
- parentSpanId,
252
- spanKind,
253
- startTime: options.startTime
254
- });
255
- for (const sp of this.spanProcessors) {
256
- sp.onStart(span2, context2);
257
- }
258
- return span2;
259
- }
260
- startActiveSpan(name, ...args) {
261
- const options = args.length > 1 ? args[0] : void 0;
262
- const parentContext = args.length > 2 ? args[1] : context.active();
263
- const fn = args.at(-1);
264
- const span2 = this.startSpan(name, options, parentContext);
265
- const contextWithSpanSet = trace.setSpan(parentContext, span2);
266
- return context.with(contextWithSpanSet, fn, void 0, span2);
267
- }
160
+ spanProcessors;
161
+ resource;
162
+ headSampler;
163
+ constructor(spanProcessors, resource) {
164
+ this.spanProcessors = spanProcessors;
165
+ this.resource = resource;
166
+ }
167
+ /**
168
+ * Set the head sampler (called from config)
169
+ */
170
+ setHeadSampler(sampler) {
171
+ this.headSampler = sampler;
172
+ }
173
+ /**
174
+ * Force flush spans for a specific trace
175
+ */
176
+ async forceFlush(traceId) {
177
+ const promises = this.spanProcessors.map(async (spanProcessor) => {
178
+ await spanProcessor.forceFlush(traceId);
179
+ });
180
+ await Promise.allSettled(promises);
181
+ }
182
+ /**
183
+ * Add extra resource attributes
184
+ */
185
+ addToResource(extra) {
186
+ this.resource.merge(extra);
187
+ }
188
+ /**
189
+ * Start a new span
190
+ */
191
+ startSpan(name, options = {}, context = context$1.active()) {
192
+ if (options.root) context = trace$1.deleteSpan(context);
193
+ if (!this.headSampler) throw new Error("Head sampler not configured. This is a bug in the instrumentation logic");
194
+ const parentSpanContext = trace$1.getSpan(context)?.spanContext();
195
+ const { traceId, randomTraceFlag } = getTraceInfo(parentSpanContext);
196
+ const spanKind = options.kind || 0;
197
+ const sanitisedAttrs = sanitizeAttributes(options.attributes);
198
+ const { decision, traceState, attributes: attrs } = (options.sampler || this.headSampler).shouldSample(context, traceId, name, spanKind, sanitisedAttrs, []);
199
+ const attributes = Object.assign({}, options.attributes, attrs, withNextSpanAttributes);
200
+ withNextSpanAttributes = {};
201
+ const spanId = idGenerator.generateSpanId();
202
+ const parentSpanId = parentSpanContext?.spanId;
203
+ const spanContext = {
204
+ traceId,
205
+ spanId,
206
+ traceFlags: (decision === SamplingDecision.RECORD_AND_SAMPLED ? 1 : 0) + randomTraceFlag,
207
+ traceState
208
+ };
209
+ const span = new SpanImpl({
210
+ attributes: sanitizeAttributes(attributes),
211
+ name,
212
+ onEnd: (span) => {
213
+ for (const sp of this.spanProcessors) sp.onEnd(span);
214
+ },
215
+ resource: this.resource,
216
+ spanContext,
217
+ parentSpanContext,
218
+ parentSpanId,
219
+ spanKind,
220
+ startTime: options.startTime
221
+ });
222
+ for (const sp of this.spanProcessors) sp.onStart(span, context);
223
+ return span;
224
+ }
225
+ startActiveSpan(name, ...args) {
226
+ const options = args.length > 1 ? args[0] : void 0;
227
+ const parentContext = args.length > 2 ? args[1] : context$1.active();
228
+ const fn = args.at(-1);
229
+ const span = this.startSpan(name, options, parentContext);
230
+ const contextWithSpanSet = trace$1.setSpan(parentContext, span);
231
+ return context$1.with(contextWithSpanSet, fn, void 0, span);
232
+ }
268
233
  };
234
+ /**
235
+ * Set attributes for the next span created
236
+ */
269
237
  function withNextSpan(attrs) {
270
- withNextSpanAttributes = Object.assign({}, withNextSpanAttributes, attrs);
238
+ withNextSpanAttributes = Object.assign({}, withNextSpanAttributes, attrs);
271
239
  }
272
240
  function getTraceInfo(parentSpanContext) {
273
- if (parentSpanContext && trace.isSpanContextValid(parentSpanContext)) {
274
- const { traceId, traceFlags } = parentSpanContext;
275
- return { traceId, randomTraceFlag: getFlagAt(traceFlags, 2) };
276
- } else {
277
- return {
278
- traceId: idGenerator.generateTraceId(),
279
- randomTraceFlag: NewTraceFlags.RANDOM_TRACE_ID_SET
280
- };
281
- }
241
+ if (parentSpanContext && trace$1.isSpanContextValid(parentSpanContext)) {
242
+ const { traceId, traceFlags } = parentSpanContext;
243
+ return {
244
+ traceId,
245
+ randomTraceFlag: getFlagAt(traceFlags, 2)
246
+ };
247
+ } else return {
248
+ traceId: idGenerator.generateTraceId(),
249
+ randomTraceFlag: NewTraceFlags.RANDOM_TRACE_ID_SET
250
+ };
282
251
  }
283
- var ADD_LISTENER_METHODS = [
284
- "addListener",
285
- "on",
286
- "once",
287
- "prependListener",
288
- "prependOnceListener"
252
+
253
+ //#endregion
254
+ //#region src/core/context.ts
255
+ const ADD_LISTENER_METHODS = [
256
+ "addListener",
257
+ "on",
258
+ "once",
259
+ "prependListener",
260
+ "prependOnceListener"
289
261
  ];
290
262
  var AbstractAsyncHooksContextManager = class {
291
- /**
292
- * Binds a context to the target function or event emitter
293
- */
294
- bind(context2, target) {
295
- if (target instanceof EventEmitter) {
296
- return this._bindEventEmitter(context2, target);
297
- }
298
- if (typeof target === "function") {
299
- return this._bindFunction(context2, target);
300
- }
301
- return target;
302
- }
303
- _bindFunction(context2, target) {
304
- const manager = this;
305
- const contextWrapper = function(...args) {
306
- return manager.with(context2, () => target.apply(this, args));
307
- };
308
- Object.defineProperty(contextWrapper, "length", {
309
- enumerable: false,
310
- configurable: true,
311
- writable: false,
312
- value: target.length
313
- });
314
- return contextWrapper;
315
- }
316
- /**
317
- * By default, EventEmitter calls callbacks with their context, which we do
318
- * not want. Instead we bind a specific context to all callbacks.
319
- */
320
- _bindEventEmitter(context2, ee) {
321
- const map = this._getPatchMap(ee);
322
- if (map !== void 0) return ee;
323
- this._createPatchMap(ee);
324
- for (const methodName of ADD_LISTENER_METHODS) {
325
- if (ee[methodName] === void 0) continue;
326
- ee[methodName] = this._patchAddListener(ee, ee[methodName], context2);
327
- }
328
- if (typeof ee.removeListener === "function") {
329
- ee.removeListener = this._patchRemoveListener(ee, ee.removeListener);
330
- }
331
- if (typeof ee.off === "function") {
332
- ee.off = this._patchRemoveListener(ee, ee.off);
333
- }
334
- if (typeof ee.removeAllListeners === "function") {
335
- ee.removeAllListeners = this._patchRemoveAllListeners(
336
- ee,
337
- ee.removeAllListeners
338
- );
339
- }
340
- return ee;
341
- }
342
- _patchRemoveListener(ee, original) {
343
- const contextManager = this;
344
- return function(event, listener) {
345
- const events = contextManager._getPatchMap(ee)?.[event];
346
- if (events === void 0) {
347
- return original.call(this, event, listener);
348
- }
349
- const patchedListener = events.get(listener);
350
- return original.call(this, event, patchedListener || listener);
351
- };
352
- }
353
- _patchRemoveAllListeners(ee, original) {
354
- const contextManager = this;
355
- return function(event) {
356
- const map = contextManager._getPatchMap(ee);
357
- if (map !== void 0) {
358
- if (arguments.length === 0) {
359
- contextManager._createPatchMap(ee);
360
- } else if (map[event] !== void 0) {
361
- delete map[event];
362
- }
363
- }
364
- return Reflect.apply(original, this, arguments);
365
- };
366
- }
367
- _patchAddListener(ee, original, context2) {
368
- const contextManager = this;
369
- return function(event, listener) {
370
- if (contextManager._wrapped) {
371
- return original.call(this, event, listener);
372
- }
373
- let map = contextManager._getPatchMap(ee);
374
- if (map === void 0) {
375
- map = contextManager._createPatchMap(ee);
376
- }
377
- let listeners = map[event];
378
- if (listeners === void 0) {
379
- listeners = /* @__PURE__ */ new WeakMap();
380
- map[event] = listeners;
381
- }
382
- const patchedListener = contextManager.bind(context2, listener);
383
- listeners.set(listener, patchedListener);
384
- contextManager._wrapped = true;
385
- try {
386
- return original.call(this, event, patchedListener);
387
- } finally {
388
- contextManager._wrapped = false;
389
- }
390
- };
391
- }
392
- _createPatchMap(ee) {
393
- const map = /* @__PURE__ */ Object.create(null);
394
- ee[this._kOtListeners] = map;
395
- return map;
396
- }
397
- _getPatchMap(ee) {
398
- return ee[this._kOtListeners];
399
- }
400
- _kOtListeners = /* @__PURE__ */ Symbol("OtListeners");
401
- _wrapped = false;
263
+ /**
264
+ * Binds a context to the target function or event emitter
265
+ */
266
+ bind(context, target) {
267
+ if (target instanceof EventEmitter) return this._bindEventEmitter(context, target);
268
+ if (typeof target === "function") return this._bindFunction(context, target);
269
+ return target;
270
+ }
271
+ _bindFunction(context, target) {
272
+ const manager = this;
273
+ const contextWrapper = function(...args) {
274
+ return manager.with(context, () => target.apply(this, args));
275
+ };
276
+ Object.defineProperty(contextWrapper, "length", {
277
+ enumerable: false,
278
+ configurable: true,
279
+ writable: false,
280
+ value: target.length
281
+ });
282
+ return contextWrapper;
283
+ }
284
+ /**
285
+ * By default, EventEmitter calls callbacks with their context, which we do
286
+ * not want. Instead we bind a specific context to all callbacks.
287
+ */
288
+ _bindEventEmitter(context, ee) {
289
+ if (this._getPatchMap(ee) !== void 0) return ee;
290
+ this._createPatchMap(ee);
291
+ for (const methodName of ADD_LISTENER_METHODS) {
292
+ if (ee[methodName] === void 0) continue;
293
+ ee[methodName] = this._patchAddListener(ee, ee[methodName], context);
294
+ }
295
+ if (typeof ee.removeListener === "function") ee.removeListener = this._patchRemoveListener(ee, ee.removeListener);
296
+ if (typeof ee.off === "function") ee.off = this._patchRemoveListener(ee, ee.off);
297
+ if (typeof ee.removeAllListeners === "function") ee.removeAllListeners = this._patchRemoveAllListeners(ee, ee.removeAllListeners);
298
+ return ee;
299
+ }
300
+ _patchRemoveListener(ee, original) {
301
+ const contextManager = this;
302
+ return function(event, listener) {
303
+ const events = contextManager._getPatchMap(ee)?.[event];
304
+ if (events === void 0) return original.call(this, event, listener);
305
+ const patchedListener = events.get(listener);
306
+ return original.call(this, event, patchedListener || listener);
307
+ };
308
+ }
309
+ _patchRemoveAllListeners(ee, original) {
310
+ const contextManager = this;
311
+ return function(event) {
312
+ const map = contextManager._getPatchMap(ee);
313
+ if (map !== void 0) {
314
+ if (arguments.length === 0) contextManager._createPatchMap(ee);
315
+ else if (map[event] !== void 0) delete map[event];
316
+ }
317
+ return Reflect.apply(original, this, arguments);
318
+ };
319
+ }
320
+ _patchAddListener(ee, original, context) {
321
+ const contextManager = this;
322
+ return function(event, listener) {
323
+ /**
324
+ * This check prevents double-wrapping the listener.
325
+ * The implementation for ee.once wraps the listener and calls ee.on.
326
+ * Without this check, we would wrap that wrapped listener.
327
+ */
328
+ if (contextManager._wrapped) return original.call(this, event, listener);
329
+ let map = contextManager._getPatchMap(ee);
330
+ if (map === void 0) map = contextManager._createPatchMap(ee);
331
+ let listeners = map[event];
332
+ if (listeners === void 0) {
333
+ listeners = /* @__PURE__ */ new WeakMap();
334
+ map[event] = listeners;
335
+ }
336
+ const patchedListener = contextManager.bind(context, listener);
337
+ listeners.set(listener, patchedListener);
338
+ contextManager._wrapped = true;
339
+ try {
340
+ return original.call(this, event, patchedListener);
341
+ } finally {
342
+ contextManager._wrapped = false;
343
+ }
344
+ };
345
+ }
346
+ _createPatchMap(ee) {
347
+ const map = Object.create(null);
348
+ ee[this._kOtListeners] = map;
349
+ return map;
350
+ }
351
+ _getPatchMap(ee) {
352
+ return ee[this._kOtListeners];
353
+ }
354
+ _kOtListeners = Symbol("OtListeners");
355
+ _wrapped = false;
402
356
  };
357
+ /**
358
+ * AsyncLocalStorage-based context manager for edge runtimes
359
+ */
403
360
  var AsyncLocalStorageContextManager = class extends AbstractAsyncHooksContextManager {
404
- _asyncLocalStorage;
405
- constructor() {
406
- super();
407
- this._asyncLocalStorage = new AsyncLocalStorage();
408
- }
409
- active() {
410
- return this._asyncLocalStorage.getStore() ?? ROOT_CONTEXT;
411
- }
412
- with(context2, fn, thisArg, ...args) {
413
- const cb = thisArg == null ? fn : fn.bind(thisArg);
414
- return this._asyncLocalStorage.run(context2, cb, ...args);
415
- }
416
- enable() {
417
- return this;
418
- }
419
- disable() {
420
- this._asyncLocalStorage.disable();
421
- return this;
422
- }
361
+ _asyncLocalStorage;
362
+ constructor() {
363
+ super();
364
+ this._asyncLocalStorage = new AsyncLocalStorage();
365
+ }
366
+ active() {
367
+ return this._asyncLocalStorage.getStore() ?? ROOT_CONTEXT;
368
+ }
369
+ with(context, fn, thisArg, ...args) {
370
+ const cb = thisArg == null ? fn : fn.bind(thisArg);
371
+ return this._asyncLocalStorage.run(context, cb, ...args);
372
+ }
373
+ enable() {
374
+ return this;
375
+ }
376
+ disable() {
377
+ this._asyncLocalStorage.disable();
378
+ return this;
379
+ }
423
380
  };
381
+
382
+ //#endregion
383
+ //#region src/core/provider.ts
384
+ /**
385
+ * Tracer provider for edge environments
386
+ */
387
+ let globalContextManagerRegistered = false;
388
+ /**
389
+ * WorkerTracerProvider - Registers tracer globally
390
+ */
424
391
  var WorkerTracerProvider = class {
425
- tracer;
426
- contextManager;
427
- constructor(spanProcessors, resource) {
428
- this.tracer = new WorkerTracer(spanProcessors, resource);
429
- this.contextManager = new AsyncLocalStorageContextManager();
430
- }
431
- /**
432
- * Get the tracer instance
433
- */
434
- getTracer(_name, _version, _config) {
435
- return this.tracer;
436
- }
437
- /**
438
- * Register this provider as the global tracer
439
- */
440
- register() {
441
- this.contextManager.enable();
442
- const provider = {
443
- getTracer: (_name, _version) => this.tracer
444
- };
445
- trace.setGlobalTracerProvider(provider);
446
- }
392
+ tracer;
393
+ contextManager;
394
+ constructor(spanProcessors, resource) {
395
+ this.tracer = new WorkerTracer(spanProcessors, resource);
396
+ this.contextManager = new AsyncLocalStorageContextManager();
397
+ }
398
+ /**
399
+ * Get the tracer instance
400
+ */
401
+ getTracer(_name, _version, _config) {
402
+ return this.tracer;
403
+ }
404
+ /**
405
+ * Register this provider as the global tracer
406
+ */
407
+ register() {
408
+ this.contextManager.enable();
409
+ if (!globalContextManagerRegistered) globalContextManagerRegistered = context$1.setGlobalContextManager(this.contextManager);
410
+ trace$1.setGlobalTracerProvider({ getTracer: (_name, _version) => this.tracer });
411
+ }
447
412
  };
413
+
414
+ //#endregion
415
+ //#region src/core/buffer.ts
416
+ /**
417
+ * Buffer polyfill for edge environments
418
+ *
419
+ * Cloudflare Workers and other edge runtimes need the Buffer global
420
+ * for OpenTelemetry OTLP serialization.
421
+ */
448
422
  globalThis.Buffer = Buffer;
449
- var TRACE_FACTORY_MARK = "__autotelEdgeTraceFactory";
450
- var INSTRUMENTED_MARK = "__autotelEdgeInstrumented";
451
- var FACTORY_NAME_HINTS = {
452
- ctx: true,
453
- _ctx: true,
454
- context: true,
455
- tracecontext: true,
456
- tracectx: true
423
+
424
+ //#endregion
425
+ //#region src/functional.ts
426
+ /**
427
+ * Functional API for autotel-edge
428
+ *
429
+ * Provides zero-boilerplate tracing helpers that mirror the Node.js runtime
430
+ * implementation while staying optimized for edge environments.
431
+ */
432
+ const TRACE_FACTORY_MARK = "__autotelEdgeTraceFactory";
433
+ const INSTRUMENTED_MARK = "__autotelEdgeInstrumented";
434
+ const FACTORY_NAME_HINTS = {
435
+ ctx: true,
436
+ _ctx: true,
437
+ context: true,
438
+ tracecontext: true,
439
+ tracectx: true
457
440
  };
458
- var SINGLE_LINE_COMMENT_REGEX = /\/\/.*$/gm;
459
- var MULTI_LINE_COMMENT_REGEX = /\/\*[\s\S]*?\*\//gm;
460
- var PARAM_TOKEN_SANITIZE_REGEX = new RegExp(String.raw`[{}\[\]\s]`, "g");
441
+ const SINGLE_LINE_COMMENT_REGEX = /\/\/.*$/gm;
442
+ const MULTI_LINE_COMMENT_REGEX = /\/\*[\s\S]*?\*\//gm;
443
+ const PARAM_TOKEN_SANITIZE_REGEX = new RegExp(String.raw`[{}\[\]\s]`, "g");
461
444
  function markAsTraceFactory(fn) {
462
- try {
463
- Object.defineProperty(fn, TRACE_FACTORY_MARK, {
464
- value: true,
465
- configurable: true
466
- });
467
- } catch {
468
- fn[TRACE_FACTORY_MARK] = true;
469
- }
445
+ try {
446
+ Object.defineProperty(fn, TRACE_FACTORY_MARK, {
447
+ value: true,
448
+ configurable: true
449
+ });
450
+ } catch {
451
+ fn[TRACE_FACTORY_MARK] = true;
452
+ }
470
453
  }
471
454
  function hasFactoryMark(fn) {
472
- return Boolean(fn[TRACE_FACTORY_MARK]);
455
+ return Boolean(fn[TRACE_FACTORY_MARK]);
473
456
  }
474
457
  function sanitizeParameterToken(token) {
475
- const [firstToken] = token.split("=");
476
- return (firstToken ?? "").replaceAll(PARAM_TOKEN_SANITIZE_REGEX, "").trim();
458
+ const [firstToken] = token.split("=");
459
+ return (firstToken ?? "").replaceAll(PARAM_TOKEN_SANITIZE_REGEX, "").trim();
477
460
  }
478
461
  function getFirstParameterToken(fn) {
479
- let source = Function.prototype.toString.call(fn);
480
- source = source.replaceAll(MULTI_LINE_COMMENT_REGEX, "").replaceAll(SINGLE_LINE_COMMENT_REGEX, "").trim();
481
- const arrowMatch = source.match(/^(?:async\s*)?(?:\(([^)]*)\)|([^=()]+))\s*=>/);
482
- if (arrowMatch) {
483
- const params = (arrowMatch[1] ?? arrowMatch[2] ?? "").split(",");
484
- const first = params[0]?.trim();
485
- if (first) {
486
- return sanitizeParameterToken(first);
487
- }
488
- return null;
489
- }
490
- const functionMatch = source.match(/^[^(]*\(([^)]*)\)/);
491
- if (functionMatch) {
492
- const params = functionMatch[1]?.split(",");
493
- const first = params?.[0]?.trim();
494
- if (first) {
495
- return sanitizeParameterToken(first);
496
- }
497
- }
498
- return null;
462
+ let source = Function.prototype.toString.call(fn);
463
+ source = source.replaceAll(MULTI_LINE_COMMENT_REGEX, "").replaceAll(SINGLE_LINE_COMMENT_REGEX, "").trim();
464
+ const arrowMatch = source.match(/^(?:async\s*)?(?:\(([^)]*)\)|([^=()]+))\s*=>/);
465
+ if (arrowMatch) {
466
+ const first = (arrowMatch[1] ?? arrowMatch[2] ?? "").split(",")[0]?.trim();
467
+ if (first) return sanitizeParameterToken(first);
468
+ return null;
469
+ }
470
+ const functionMatch = source.match(/^[^(]*\(([^)]*)\)/);
471
+ if (functionMatch) {
472
+ const first = (functionMatch[1]?.split(","))?.[0]?.trim();
473
+ if (first) return sanitizeParameterToken(first);
474
+ }
475
+ return null;
499
476
  }
500
477
  function looksLikeTraceFactory(fn) {
501
- if (hasFactoryMark(fn)) {
502
- return true;
503
- }
504
- if (fn.length === 0) {
505
- return false;
506
- }
507
- const firstParam = getFirstParameterToken(fn);
508
- if (!firstParam) {
509
- return false;
510
- }
511
- const normalized = firstParam.toLowerCase();
512
- if (Object.hasOwn(FACTORY_NAME_HINTS, normalized) || normalized.startsWith("ctx") || normalized.startsWith("_ctx") || normalized.startsWith("trace")) {
513
- return true;
514
- }
515
- return false;
516
- }
478
+ if (hasFactoryMark(fn)) return true;
479
+ if (fn.length === 0) return false;
480
+ const firstParam = getFirstParameterToken(fn);
481
+ if (!firstParam) return false;
482
+ const normalized = firstParam.toLowerCase();
483
+ if (Object.hasOwn(FACTORY_NAME_HINTS, normalized) || normalized.startsWith("ctx") || normalized.startsWith("_ctx") || normalized.startsWith("trace")) return true;
484
+ return false;
485
+ }
486
+ /**
487
+ * Check if a function that takes ctx returns another function (factory pattern)
488
+ * vs returning a value directly (immediate execution pattern)
489
+ */
517
490
  function isFactoryReturningFunction(fnWithCtx) {
518
- try {
519
- const result = fnWithCtx(createDummyCtx());
520
- return typeof result === "function";
521
- } catch {
522
- return false;
523
- }
491
+ try {
492
+ return typeof fnWithCtx(createDummyCtx()) === "function";
493
+ } catch {
494
+ return false;
495
+ }
524
496
  }
525
497
  function isTraceFactoryFunction(fn) {
526
- if (typeof fn !== "function") {
527
- return false;
528
- }
529
- if (hasFactoryMark(fn)) {
530
- return true;
531
- }
532
- if (looksLikeTraceFactory(fn)) {
533
- markAsTraceFactory(fn);
534
- return true;
535
- }
536
- return false;
498
+ if (typeof fn !== "function") return false;
499
+ if (hasFactoryMark(fn)) return true;
500
+ if (looksLikeTraceFactory(fn)) {
501
+ markAsTraceFactory(fn);
502
+ return true;
503
+ }
504
+ return false;
537
505
  }
538
506
  function ensureTraceFactory(fnOrFactory) {
539
- if (isTraceFactoryFunction(fnOrFactory)) {
540
- return fnOrFactory;
541
- }
542
- const plainFn = fnOrFactory;
543
- const factory = (ctx) => {
544
- return plainFn;
545
- };
546
- markAsTraceFactory(factory);
547
- return factory;
548
- }
549
- var MAX_ERROR_MESSAGE_LENGTH = 500;
507
+ if (isTraceFactoryFunction(fnOrFactory)) return fnOrFactory;
508
+ const plainFn = fnOrFactory;
509
+ const factory = (ctx) => {
510
+ return plainFn;
511
+ };
512
+ markAsTraceFactory(factory);
513
+ return factory;
514
+ }
515
+ const MAX_ERROR_MESSAGE_LENGTH = 500;
550
516
  function createDummyCtx() {
551
- return {
552
- traceId: "",
553
- spanId: "",
554
- correlationId: "",
555
- setAttribute: () => {
556
- },
557
- setAttributes: () => {
558
- },
559
- setStatus: () => {
560
- },
561
- recordException: () => {
562
- },
563
- addEvent: () => {
564
- },
565
- addLink: () => {
566
- },
567
- addLinks: () => {
568
- },
569
- updateName: () => {
570
- },
571
- isRecording: () => false
572
- };
517
+ return {
518
+ traceId: "",
519
+ spanId: "",
520
+ correlationId: "",
521
+ setAttribute: () => {},
522
+ setAttributes: () => {},
523
+ setStatus: () => {},
524
+ recordException: () => {},
525
+ addEvent: () => {},
526
+ addLink: () => {},
527
+ addLinks: () => {},
528
+ updateName: () => {},
529
+ isRecording: () => false
530
+ };
573
531
  }
574
532
  function truncateErrorMessage(message) {
575
- if (message.length <= MAX_ERROR_MESSAGE_LENGTH) {
576
- return message;
577
- }
578
- return `${message.slice(0, MAX_ERROR_MESSAGE_LENGTH)}... (truncated)`;
533
+ if (message.length <= MAX_ERROR_MESSAGE_LENGTH) return message;
534
+ return `${message.slice(0, MAX_ERROR_MESSAGE_LENGTH)}... (truncated)`;
579
535
  }
580
536
  function inferFunctionName(fn) {
581
- const displayName = fn.displayName;
582
- if (displayName) {
583
- return displayName;
584
- }
585
- if (fn.name && fn.name !== "anonymous") {
586
- return fn.name;
587
- }
588
- const source = Function.prototype.toString.call(fn);
589
- const match = source.match(/function\s+([^(\s]+)/);
590
- if (match && match[1] && match[1] !== "anonymous") {
591
- return match[1];
592
- }
593
- return void 0;
537
+ const displayName = fn.displayName;
538
+ if (displayName) return displayName;
539
+ if (fn.name && fn.name !== "anonymous") return fn.name;
540
+ const match = Function.prototype.toString.call(fn).match(/function\s+([^(\s]+)/);
541
+ if (match && match[1] && match[1] !== "anonymous") return match[1];
594
542
  }
595
543
  function getSpanName(options, fn, variableName) {
596
- if (options.name) {
597
- return options.name;
598
- }
599
- let fnName = variableName ?? inferFunctionName(fn);
600
- fnName = fnName || "anonymous";
601
- if (options.serviceName) {
602
- return `${options.serviceName}.${fnName}`;
603
- }
604
- if (fnName && fnName !== "anonymous") {
605
- return fnName;
606
- }
607
- return "unknown";
544
+ if (options.name) return options.name;
545
+ let fnName = variableName ?? inferFunctionName(fn);
546
+ fnName = fnName || "anonymous";
547
+ if (options.serviceName) return `${options.serviceName}.${fnName}`;
548
+ if (fnName && fnName !== "anonymous") return fnName;
549
+ return "unknown";
608
550
  }
609
551
  function isAsyncFunction(fn) {
610
- return typeof fn === "function" && fn.constructor?.name === "AsyncFunction";
552
+ return typeof fn === "function" && fn.constructor?.name === "AsyncFunction";
611
553
  }
612
554
  function wrapWithTracingAsync(fnFactory, options, variableName) {
613
- const tempFn = fnFactory(createDummyCtx());
614
- const spanName = getSpanName(options, tempFn, variableName);
615
- const wrappedFunction = async function wrappedFunction2(...args) {
616
- const tracer = trace.getTracer("autotel-edge");
617
- const spanOptions = options.sampler ? { sampler: options.sampler } : {};
618
- return tracer.startActiveSpan(spanName, spanOptions, async (span2) => {
619
- setSpanName(span2, spanName);
620
- try {
621
- const actualFn = fnFactory(createTraceContext(span2));
622
- if (options.attributes) {
623
- span2.setAttributes(options.attributes);
624
- }
625
- if (options.attributesFromArgs) {
626
- const argsAttrs = options.attributesFromArgs(args);
627
- span2.setAttributes(argsAttrs);
628
- }
629
- const result = await actualFn(...args);
630
- if (options.attributesFromResult) {
631
- const resultAttrs = options.attributesFromResult(result);
632
- span2.setAttributes(resultAttrs);
633
- }
634
- span2.setAttribute("code.function", spanName);
635
- span2.setStatus({ code: SpanStatusCode.OK });
636
- span2.end();
637
- return result;
638
- } catch (error) {
639
- const message = truncateErrorMessage(
640
- error instanceof Error ? error.message : String(error ?? "Unknown error")
641
- );
642
- span2.setAttribute("code.function", spanName);
643
- span2.setStatus({ code: SpanStatusCode.ERROR, message });
644
- span2.recordException(error instanceof Error ? error : new Error(String(error)));
645
- span2.end();
646
- throw error;
647
- }
648
- });
649
- };
650
- Object.defineProperty(wrappedFunction, "name", {
651
- value: tempFn.name || "trace",
652
- configurable: true
653
- });
654
- wrappedFunction[INSTRUMENTED_MARK] = true;
655
- return wrappedFunction;
555
+ const tempFn = fnFactory(createDummyCtx());
556
+ const spanName = getSpanName(options, tempFn, variableName);
557
+ const wrappedFunction = async function wrappedFunction(...args) {
558
+ const tracer = trace$1.getTracer("autotel-edge");
559
+ const spanOptions = options.sampler ? { sampler: options.sampler } : {};
560
+ return tracer.startActiveSpan(spanName, spanOptions, async (span) => {
561
+ setSpanName(span, spanName);
562
+ try {
563
+ const actualFn = fnFactory(createTraceContext(span));
564
+ if (options.attributes) span.setAttributes(options.attributes);
565
+ if (options.attributesFromArgs) {
566
+ const argsAttrs = options.attributesFromArgs(args);
567
+ span.setAttributes(argsAttrs);
568
+ }
569
+ const result = await actualFn(...args);
570
+ if (options.attributesFromResult) {
571
+ const resultAttrs = options.attributesFromResult(result);
572
+ span.setAttributes(resultAttrs);
573
+ }
574
+ span.setAttribute("code.function", spanName);
575
+ span.setStatus({ code: SpanStatusCode.OK });
576
+ span.end();
577
+ return result;
578
+ } catch (error) {
579
+ const message = truncateErrorMessage(error instanceof Error ? error.message : String(error ?? "Unknown error"));
580
+ span.setAttribute("code.function", spanName);
581
+ span.setStatus({
582
+ code: SpanStatusCode.ERROR,
583
+ message
584
+ });
585
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
586
+ span.end();
587
+ throw error;
588
+ }
589
+ });
590
+ };
591
+ Object.defineProperty(wrappedFunction, "name", {
592
+ value: tempFn.name || "trace",
593
+ configurable: true
594
+ });
595
+ wrappedFunction[INSTRUMENTED_MARK] = true;
596
+ return wrappedFunction;
656
597
  }
657
598
  function wrapWithTracingSync(fnFactory, options, variableName) {
658
- const tempFn = fnFactory(createDummyCtx());
659
- const spanName = getSpanName(options, tempFn, variableName);
660
- const wrappedFunction = function wrappedFunction2(...args) {
661
- const tracer = trace.getTracer("autotel-edge");
662
- const spanOptions = options.sampler ? { sampler: options.sampler } : {};
663
- return tracer.startActiveSpan(spanName, spanOptions, (span2) => {
664
- setSpanName(span2, spanName);
665
- try {
666
- const actualFn = fnFactory(createTraceContext(span2));
667
- if (options.attributes) {
668
- span2.setAttributes(options.attributes);
669
- }
670
- if (options.attributesFromArgs) {
671
- const argsAttrs = options.attributesFromArgs(args);
672
- span2.setAttributes(argsAttrs);
673
- }
674
- const result = actualFn(...args);
675
- if (options.attributesFromResult) {
676
- const resultAttrs = options.attributesFromResult(result);
677
- span2.setAttributes(resultAttrs);
678
- }
679
- span2.setAttribute("code.function", spanName);
680
- span2.setStatus({ code: SpanStatusCode.OK });
681
- span2.end();
682
- return result;
683
- } catch (error) {
684
- const message = truncateErrorMessage(
685
- error instanceof Error ? error.message : String(error ?? "Unknown error")
686
- );
687
- span2.setAttribute("code.function", spanName);
688
- span2.setStatus({ code: SpanStatusCode.ERROR, message });
689
- span2.recordException(error instanceof Error ? error : new Error(String(error)));
690
- span2.end();
691
- throw error;
692
- }
693
- });
694
- };
695
- Object.defineProperty(wrappedFunction, "name", {
696
- value: tempFn.name || "trace",
697
- configurable: true
698
- });
699
- wrappedFunction[INSTRUMENTED_MARK] = true;
700
- return wrappedFunction;
599
+ const tempFn = fnFactory(createDummyCtx());
600
+ const spanName = getSpanName(options, tempFn, variableName);
601
+ const wrappedFunction = function wrappedFunction(...args) {
602
+ const tracer = trace$1.getTracer("autotel-edge");
603
+ const spanOptions = options.sampler ? { sampler: options.sampler } : {};
604
+ return tracer.startActiveSpan(spanName, spanOptions, (span) => {
605
+ setSpanName(span, spanName);
606
+ try {
607
+ const actualFn = fnFactory(createTraceContext(span));
608
+ if (options.attributes) span.setAttributes(options.attributes);
609
+ if (options.attributesFromArgs) {
610
+ const argsAttrs = options.attributesFromArgs(args);
611
+ span.setAttributes(argsAttrs);
612
+ }
613
+ const result = actualFn(...args);
614
+ if (options.attributesFromResult) {
615
+ const resultAttrs = options.attributesFromResult(result);
616
+ span.setAttributes(resultAttrs);
617
+ }
618
+ span.setAttribute("code.function", spanName);
619
+ span.setStatus({ code: SpanStatusCode.OK });
620
+ span.end();
621
+ return result;
622
+ } catch (error) {
623
+ const message = truncateErrorMessage(error instanceof Error ? error.message : String(error ?? "Unknown error"));
624
+ span.setAttribute("code.function", spanName);
625
+ span.setStatus({
626
+ code: SpanStatusCode.ERROR,
627
+ message
628
+ });
629
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
630
+ span.end();
631
+ throw error;
632
+ }
633
+ });
634
+ };
635
+ Object.defineProperty(wrappedFunction, "name", {
636
+ value: tempFn.name || "trace",
637
+ configurable: true
638
+ });
639
+ wrappedFunction[INSTRUMENTED_MARK] = true;
640
+ return wrappedFunction;
701
641
  }
702
642
  function wrapFactoryWithTracing(fnOrFactory, options, variableName) {
703
- const factory = ensureTraceFactory(fnOrFactory);
704
- const sampleFn = factory(createDummyCtx());
705
- const useAsyncWrapper = isAsyncFunction(sampleFn);
706
- if (useAsyncWrapper) {
707
- return wrapWithTracingAsync(
708
- factory,
709
- options,
710
- variableName
711
- );
712
- }
713
- return wrapWithTracingSync(
714
- factory,
715
- options,
716
- variableName
717
- );
718
- }
643
+ const factory = ensureTraceFactory(fnOrFactory);
644
+ if (isAsyncFunction(factory(createDummyCtx()))) return wrapWithTracingAsync(factory, options, variableName);
645
+ return wrapWithTracingSync(factory, options, variableName);
646
+ }
647
+ /**
648
+ * Execute a function immediately within a trace span
649
+ * Used for the immediate execution pattern: trace((ctx) => result)
650
+ */
719
651
  function executeImmediately(fn, options) {
720
- const tracer = trace.getTracer("@autotel/edge");
721
- const spanName = options.name || "anonymous";
722
- return tracer.startActiveSpan(spanName, (span2) => {
723
- try {
724
- setSpanName(span2, spanName);
725
- const ctxValue = createTraceContext(span2);
726
- const onSuccess = (result2) => {
727
- span2.setStatus({ code: SpanStatusCode.OK });
728
- if (options.attributes) {
729
- for (const [key, value] of Object.entries(options.attributes)) {
730
- span2.setAttribute(key, value);
731
- }
732
- }
733
- span2.end();
734
- return result2;
735
- };
736
- const onError = (error) => {
737
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
738
- const truncatedMessage = truncateErrorMessage(errorMessage);
739
- span2.setStatus({
740
- code: SpanStatusCode.ERROR,
741
- message: truncatedMessage
742
- });
743
- span2.setAttribute("error", true);
744
- span2.setAttribute(
745
- "exception.type",
746
- error instanceof Error ? error.constructor.name : "Error"
747
- );
748
- span2.setAttribute("exception.message", truncatedMessage);
749
- span2.recordException(
750
- error instanceof Error ? error : new Error(String(error))
751
- );
752
- span2.end();
753
- throw error;
754
- };
755
- const result = fn(ctxValue);
756
- if (result instanceof Promise) {
757
- return result.then(onSuccess, onError);
758
- }
759
- return onSuccess(result);
760
- } catch (error) {
761
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
762
- const truncatedMessage = truncateErrorMessage(errorMessage);
763
- span2.setStatus({
764
- code: SpanStatusCode.ERROR,
765
- message: truncatedMessage
766
- });
767
- span2.setAttribute("error", true);
768
- span2.setAttribute("exception.message", truncatedMessage);
769
- span2.recordException(
770
- error instanceof Error ? error : new Error(String(error))
771
- );
772
- span2.end();
773
- throw error;
774
- }
775
- });
776
- }
777
- function trace3(fnOrNameOrOptions, maybeFn) {
778
- if (typeof fnOrNameOrOptions === "function") {
779
- if (looksLikeTraceFactory(fnOrNameOrOptions) && !isFactoryReturningFunction(fnOrNameOrOptions)) {
780
- return executeImmediately(
781
- fnOrNameOrOptions,
782
- {}
783
- );
784
- }
785
- return wrapFactoryWithTracing(
786
- fnOrNameOrOptions,
787
- {}
788
- );
789
- }
790
- if (typeof fnOrNameOrOptions === "string") {
791
- if (!maybeFn) {
792
- throw new Error("trace(name, fn): fn is required");
793
- }
794
- if (looksLikeTraceFactory(maybeFn) && !isFactoryReturningFunction(maybeFn)) {
795
- return executeImmediately(
796
- maybeFn,
797
- { name: fnOrNameOrOptions }
798
- );
799
- }
800
- return wrapFactoryWithTracing(
801
- maybeFn,
802
- { name: fnOrNameOrOptions }
803
- );
804
- }
805
- if (!maybeFn) {
806
- throw new Error("trace(options, fn): fn is required");
807
- }
808
- if (looksLikeTraceFactory(maybeFn) && !isFactoryReturningFunction(maybeFn)) {
809
- return executeImmediately(
810
- maybeFn,
811
- fnOrNameOrOptions
812
- );
813
- }
814
- return wrapFactoryWithTracing(
815
- maybeFn,
816
- fnOrNameOrOptions
817
- );
652
+ const tracer = trace$1.getTracer("@autotel/edge");
653
+ const spanName = options.name || "anonymous";
654
+ return tracer.startActiveSpan(spanName, (span) => {
655
+ try {
656
+ setSpanName(span, spanName);
657
+ const ctxValue = createTraceContext(span);
658
+ const onSuccess = (result) => {
659
+ span.setStatus({ code: SpanStatusCode.OK });
660
+ if (options.attributes) for (const [key, value] of Object.entries(options.attributes)) span.setAttribute(key, value);
661
+ span.end();
662
+ return result;
663
+ };
664
+ const onError = (error) => {
665
+ const truncatedMessage = truncateErrorMessage(error instanceof Error ? error.message : "Unknown error");
666
+ span.setStatus({
667
+ code: SpanStatusCode.ERROR,
668
+ message: truncatedMessage
669
+ });
670
+ span.setAttribute("error", true);
671
+ span.setAttribute("exception.type", error instanceof Error ? error.constructor.name : "Error");
672
+ span.setAttribute("exception.message", truncatedMessage);
673
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
674
+ span.end();
675
+ throw error;
676
+ };
677
+ const result = fn(ctxValue);
678
+ if (result instanceof Promise) return result.then(onSuccess, onError);
679
+ return onSuccess(result);
680
+ } catch (error) {
681
+ const truncatedMessage = truncateErrorMessage(error instanceof Error ? error.message : "Unknown error");
682
+ span.setStatus({
683
+ code: SpanStatusCode.ERROR,
684
+ message: truncatedMessage
685
+ });
686
+ span.setAttribute("error", true);
687
+ span.setAttribute("exception.message", truncatedMessage);
688
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
689
+ span.end();
690
+ throw error;
691
+ }
692
+ });
693
+ }
694
+ function trace(fnOrNameOrOptions, maybeFn) {
695
+ if (typeof fnOrNameOrOptions === "function") {
696
+ if (looksLikeTraceFactory(fnOrNameOrOptions) && !isFactoryReturningFunction(fnOrNameOrOptions)) return executeImmediately(fnOrNameOrOptions, {});
697
+ return wrapFactoryWithTracing(fnOrNameOrOptions, {});
698
+ }
699
+ if (typeof fnOrNameOrOptions === "string") {
700
+ if (!maybeFn) throw new Error("trace(name, fn): fn is required");
701
+ if (looksLikeTraceFactory(maybeFn) && !isFactoryReturningFunction(maybeFn)) return executeImmediately(maybeFn, { name: fnOrNameOrOptions });
702
+ return wrapFactoryWithTracing(maybeFn, { name: fnOrNameOrOptions });
703
+ }
704
+ if (!maybeFn) throw new Error("trace(options, fn): fn is required");
705
+ if (looksLikeTraceFactory(maybeFn) && !isFactoryReturningFunction(maybeFn)) return executeImmediately(maybeFn, fnOrNameOrOptions);
706
+ return wrapFactoryWithTracing(maybeFn, fnOrNameOrOptions);
818
707
  }
819
708
  function withTracing(options) {
820
- return (fnOrFactory) => wrapFactoryWithTracing(fnOrFactory, options);
709
+ return (fnOrFactory) => wrapFactoryWithTracing(fnOrFactory, options);
821
710
  }
822
711
  function shouldSkip(key, fn, skip) {
823
- if (key.startsWith("_")) {
824
- return true;
825
- }
826
- if (!skip || skip.length === 0) {
827
- return false;
828
- }
829
- for (const pattern of skip) {
830
- if (typeof pattern === "string" && key === pattern) {
831
- return true;
832
- }
833
- if (pattern instanceof RegExp && pattern.test(key)) {
834
- return true;
835
- }
836
- if (typeof pattern === "function" && pattern(key, fn)) {
837
- return true;
838
- }
839
- }
840
- return false;
712
+ if (key.startsWith("_")) return true;
713
+ if (!skip || skip.length === 0) return false;
714
+ for (const pattern of skip) {
715
+ if (typeof pattern === "string" && key === pattern) return true;
716
+ if (pattern instanceof RegExp && pattern.test(key)) return true;
717
+ if (typeof pattern === "function" && pattern(key, fn)) return true;
718
+ }
719
+ return false;
841
720
  }
842
721
  function instrument(options) {
843
- const { functions, ...tracingOptions } = options;
844
- const instrumented = {};
845
- for (const key of Object.keys(functions)) {
846
- const fn = functions[key];
847
- if (typeof fn !== "function") {
848
- instrumented[key] = fn;
849
- continue;
850
- }
851
- if (shouldSkip(key, fn, tracingOptions.skip)) {
852
- instrumented[key] = fn;
853
- continue;
854
- }
855
- const fnOptions = {
856
- ...tracingOptions,
857
- ...tracingOptions.overrides?.[key],
858
- name: tracingOptions.overrides?.[key]?.name ?? tracingOptions.name
859
- };
860
- const boundFn = fn.bind(functions);
861
- const fnFactory = (_ctx) => boundFn;
862
- instrumented[key] = wrapFactoryWithTracing(fnFactory, fnOptions, key);
863
- }
864
- return instrumented;
722
+ const { functions, ...tracingOptions } = options;
723
+ const instrumented = {};
724
+ for (const key of Object.keys(functions)) {
725
+ const fn = functions[key];
726
+ if (typeof fn !== "function") {
727
+ instrumented[key] = fn;
728
+ continue;
729
+ }
730
+ if (shouldSkip(key, fn, tracingOptions.skip)) {
731
+ instrumented[key] = fn;
732
+ continue;
733
+ }
734
+ const fnOptions = {
735
+ ...tracingOptions,
736
+ ...tracingOptions.overrides?.[key],
737
+ name: tracingOptions.overrides?.[key]?.name ?? tracingOptions.name
738
+ };
739
+ const boundFn = fn.bind(functions);
740
+ const fnFactory = (_ctx) => boundFn;
741
+ instrumented[key] = wrapFactoryWithTracing(fnFactory, fnOptions, key);
742
+ }
743
+ return instrumented;
865
744
  }
866
745
  function span(nameOrOptions, fn) {
867
- const options = typeof nameOrOptions === "string" ? { name: nameOrOptions } : nameOrOptions;
868
- const tracer = trace.getTracer("autotel-edge");
869
- const execute = (span2) => {
870
- setSpanName(span2, options.name);
871
- try {
872
- if (options.attributes) {
873
- for (const [key, value] of Object.entries(options.attributes)) {
874
- span2.setAttribute(key, value);
875
- }
876
- }
877
- const result2 = fn(span2);
878
- if (result2 instanceof Promise) {
879
- return result2.then((value) => {
880
- span2.setAttribute("code.function", options.name);
881
- span2.setStatus({ code: SpanStatusCode.OK });
882
- span2.end();
883
- return value;
884
- }).catch((error) => {
885
- const message = truncateErrorMessage(
886
- error instanceof Error ? error.message : String(error ?? "Unknown error")
887
- );
888
- span2.setAttribute("code.function", options.name);
889
- span2.setStatus({ code: SpanStatusCode.ERROR, message });
890
- span2.recordException(error instanceof Error ? error : new Error(String(error)));
891
- span2.end();
892
- throw error;
893
- });
894
- }
895
- span2.setAttribute("code.function", options.name);
896
- span2.setStatus({ code: SpanStatusCode.OK });
897
- span2.end();
898
- return result2;
899
- } catch (error) {
900
- const message = truncateErrorMessage(
901
- error instanceof Error ? error.message : String(error ?? "Unknown error")
902
- );
903
- span2.setAttribute("code.function", options.name);
904
- span2.setStatus({ code: SpanStatusCode.ERROR, message });
905
- span2.recordException(error instanceof Error ? error : new Error(String(error)));
906
- span2.end();
907
- throw error;
908
- }
909
- };
910
- const result = tracer.startActiveSpan(options.name, execute);
911
- if (result instanceof Promise) {
912
- return result;
913
- }
914
- return result;
746
+ const options = typeof nameOrOptions === "string" ? { name: nameOrOptions } : nameOrOptions;
747
+ const tracer = trace$1.getTracer("autotel-edge");
748
+ const execute = (span) => {
749
+ setSpanName(span, options.name);
750
+ try {
751
+ if (options.attributes) for (const [key, value] of Object.entries(options.attributes)) span.setAttribute(key, value);
752
+ const result = fn(span);
753
+ if (result instanceof Promise) return result.then((value) => {
754
+ span.setAttribute("code.function", options.name);
755
+ span.setStatus({ code: SpanStatusCode.OK });
756
+ span.end();
757
+ return value;
758
+ }).catch((error) => {
759
+ const message = truncateErrorMessage(error instanceof Error ? error.message : String(error ?? "Unknown error"));
760
+ span.setAttribute("code.function", options.name);
761
+ span.setStatus({
762
+ code: SpanStatusCode.ERROR,
763
+ message
764
+ });
765
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
766
+ span.end();
767
+ throw error;
768
+ });
769
+ span.setAttribute("code.function", options.name);
770
+ span.setStatus({ code: SpanStatusCode.OK });
771
+ span.end();
772
+ return result;
773
+ } catch (error) {
774
+ const message = truncateErrorMessage(error instanceof Error ? error.message : String(error ?? "Unknown error"));
775
+ span.setAttribute("code.function", options.name);
776
+ span.setStatus({
777
+ code: SpanStatusCode.ERROR,
778
+ message
779
+ });
780
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
781
+ span.end();
782
+ throw error;
783
+ }
784
+ };
785
+ const result = tracer.startActiveSpan(options.name, execute);
786
+ if (result instanceof Promise) return result;
787
+ return result;
915
788
  }
916
789
 
917
- // src/composition.ts
790
+ //#endregion
791
+ //#region src/composition.ts
792
+ /**
793
+ * Identity helper for authoring an autotel configuration once with full
794
+ * type-checking. Mirrors `defineConfig` patterns in tools like Vite / Vitest.
795
+ *
796
+ * @example
797
+ * ```ts
798
+ * import { defineConfig } from 'autotel-edge'
799
+ *
800
+ * export const otelConfig = defineConfig({
801
+ * service: { name: 'checkout' },
802
+ * exporter: { url: process.env.OTLP_URL! },
803
+ * })
804
+ * ```
805
+ */
918
806
  function defineConfig(config) {
919
- return config;
920
- }
807
+ return config;
808
+ }
809
+ /**
810
+ * Run a list of subscribers in registration order. Errors thrown by an
811
+ * individual subscriber are caught and logged so a buggy subscriber never
812
+ * blocks the others — important because `subscribers` is the primary
813
+ * extensibility point for in-process side effects.
814
+ */
921
815
  function composeSubscribers(subscribers, options = {}) {
922
- const label = options.name ?? "compose-subscribers";
923
- return async (event) => {
924
- for (const subscriber of subscribers) {
925
- try {
926
- await subscriber(event);
927
- } catch (err) {
928
- console.error(`[autotel-edge/${label}] subscriber failed:`, err);
929
- }
930
- }
931
- };
932
- }
816
+ const label = options.name ?? "compose-subscribers";
817
+ return async (event) => {
818
+ for (const subscriber of subscribers) try {
819
+ await subscriber(event);
820
+ } catch (err) {
821
+ console.error(`[autotel-edge/${label}] subscriber failed:`, err);
822
+ }
823
+ };
824
+ }
825
+ /**
826
+ * Chain post-processors so each one sees the output of the previous one.
827
+ * This matches the standard OTel post-processor contract: take spans, return
828
+ * spans (possibly filtered, redacted, or annotated).
829
+ */
933
830
  function composePostProcessors(processors) {
934
- return (spans) => {
935
- let current = spans;
936
- for (const processor of processors) {
937
- try {
938
- current = processor(current);
939
- } catch (err) {
940
- console.error("[autotel-edge/compose-post-processors] failed:", err);
941
- }
942
- }
943
- return current;
944
- };
945
- }
831
+ return (spans) => {
832
+ let current = spans;
833
+ for (const processor of processors) try {
834
+ current = processor(current);
835
+ } catch (err) {
836
+ console.error("[autotel-edge/compose-post-processors] failed:", err);
837
+ }
838
+ return current;
839
+ };
840
+ }
841
+ /**
842
+ * Fan out span lifecycle events to multiple span processors. Any single
843
+ * processor's failure is isolated so it cannot break the others.
844
+ *
845
+ * Useful when you want to attach, say, a sampling processor + a custom
846
+ * attribute redactor + the default batch processor without having to author a
847
+ * single processor that knows about all three.
848
+ */
946
849
  function composeSpanProcessors(processors) {
947
- const safe = (label, fn) => Promise.resolve().then(fn).catch((err) => {
948
- console.error(`[autotel-edge/compose-span-processors:${label}]`, err);
949
- });
950
- return {
951
- onStart(span2, parentContext) {
952
- for (const processor of processors) {
953
- try {
954
- processor.onStart(span2, parentContext);
955
- } catch (err) {
956
- console.error("[autotel-edge/compose-span-processors:onStart]", err);
957
- }
958
- }
959
- },
960
- onEnd(span2) {
961
- for (const processor of processors) {
962
- try {
963
- processor.onEnd(span2);
964
- } catch (err) {
965
- console.error("[autotel-edge/compose-span-processors:onEnd]", err);
966
- }
967
- }
968
- },
969
- async forceFlush() {
970
- await Promise.allSettled(
971
- processors.map((p) => safe("forceFlush", () => p.forceFlush()))
972
- );
973
- },
974
- async shutdown() {
975
- await Promise.allSettled(
976
- processors.map((p) => safe("shutdown", () => p.shutdown()))
977
- );
978
- }
979
- };
850
+ const safe = (label, fn) => Promise.resolve().then(fn).catch((err) => {
851
+ console.error(`[autotel-edge/compose-span-processors:${label}]`, err);
852
+ });
853
+ return {
854
+ onStart(span, parentContext) {
855
+ for (const processor of processors) try {
856
+ processor.onStart(span, parentContext);
857
+ } catch (err) {
858
+ console.error("[autotel-edge/compose-span-processors:onStart]", err);
859
+ }
860
+ },
861
+ onEnd(span) {
862
+ for (const processor of processors) try {
863
+ processor.onEnd(span);
864
+ } catch (err) {
865
+ console.error("[autotel-edge/compose-span-processors:onEnd]", err);
866
+ }
867
+ },
868
+ async forceFlush() {
869
+ await Promise.allSettled(processors.map((p) => safe("forceFlush", () => p.forceFlush())));
870
+ },
871
+ async shutdown() {
872
+ await Promise.allSettled(processors.map((p) => safe("shutdown", () => p.shutdown())));
873
+ }
874
+ };
980
875
  }
981
876
 
982
- // src/plugin-runner.ts
877
+ //#endregion
878
+ //#region src/plugin-runner.ts
983
879
  function logPluginError(logger, name, hook, error) {
984
- logger.error(`[autotel-edge/${name}] ${hook} failed:`, error);
880
+ logger.error(`[autotel-edge/${name}] ${hook} failed:`, error);
985
881
  }
986
882
  function definePlugin(plugin) {
987
- return plugin;
883
+ return plugin;
988
884
  }
989
885
  function createPluginRunner(plugins = [], options = {}) {
990
- const errorLogger = options.logger ?? console;
991
- const byName = /* @__PURE__ */ new Map();
992
- for (const plugin of plugins) {
993
- byName.set(plugin.name, plugin);
994
- }
995
- const list = Array.from(byName.values());
996
- const hasEnrich = list.some((p) => typeof p.enrich === "function");
997
- const hasDrain = list.some((p) => typeof p.drain === "function");
998
- const hasKeep = list.some((p) => typeof p.keep === "function");
999
- const hasRequestLifecycle = list.some(
1000
- (p) => typeof p.onRequestStart === "function" || typeof p.onRequestFinish === "function"
1001
- );
1002
- const hasClientLog = list.some((p) => typeof p.onClientLog === "function");
1003
- const hasExtendLogger = list.some(
1004
- (p) => typeof p.extendLogger === "function"
1005
- );
1006
- return {
1007
- plugins: list,
1008
- hasEnrich,
1009
- hasDrain,
1010
- hasKeep,
1011
- hasRequestLifecycle,
1012
- hasClientLog,
1013
- hasExtendLogger,
1014
- applyExtendLogger(logger) {
1015
- for (const plugin of list) {
1016
- if (!plugin.extendLogger) continue;
1017
- try {
1018
- plugin.extendLogger(logger);
1019
- } catch (err) {
1020
- logPluginError(errorLogger, plugin.name, "extendLogger", err);
1021
- }
1022
- }
1023
- },
1024
- runOnRequestStart(ctx) {
1025
- for (const plugin of list) {
1026
- if (!plugin.onRequestStart) continue;
1027
- try {
1028
- plugin.onRequestStart(ctx);
1029
- } catch (err) {
1030
- logPluginError(errorLogger, plugin.name, "onRequestStart", err);
1031
- }
1032
- }
1033
- },
1034
- runOnRequestFinish(ctx) {
1035
- for (const plugin of list) {
1036
- if (!plugin.onRequestFinish) continue;
1037
- try {
1038
- plugin.onRequestFinish(ctx);
1039
- } catch (err) {
1040
- logPluginError(errorLogger, plugin.name, "onRequestFinish", err);
1041
- }
1042
- }
1043
- },
1044
- runOnClientLog(ctx) {
1045
- for (const plugin of list) {
1046
- if (!plugin.onClientLog) continue;
1047
- try {
1048
- plugin.onClientLog(ctx);
1049
- } catch (err) {
1050
- logPluginError(errorLogger, plugin.name, "onClientLog", err);
1051
- }
1052
- }
1053
- },
1054
- async runSetup(ctx) {
1055
- for (const plugin of list) {
1056
- if (!plugin.setup) continue;
1057
- try {
1058
- await plugin.setup(ctx);
1059
- } catch (err) {
1060
- logPluginError(errorLogger, plugin.name, "setup", err);
1061
- }
1062
- }
1063
- },
1064
- async runEnrich(ctx) {
1065
- for (const plugin of list) {
1066
- if (!plugin.enrich) continue;
1067
- try {
1068
- await plugin.enrich(ctx);
1069
- } catch (err) {
1070
- logPluginError(errorLogger, plugin.name, "enrich", err);
1071
- }
1072
- }
1073
- },
1074
- async runDrain(ctx) {
1075
- const drains = list.filter((p) => typeof p.drain === "function");
1076
- if (drains.length === 0) return;
1077
- await Promise.allSettled(
1078
- drains.map(async (plugin) => {
1079
- try {
1080
- await plugin.drain(ctx);
1081
- } catch (err) {
1082
- logPluginError(errorLogger, plugin.name, "drain", err);
1083
- }
1084
- })
1085
- );
1086
- },
1087
- async runKeep(ctx) {
1088
- for (const plugin of list) {
1089
- if (!plugin.keep) continue;
1090
- try {
1091
- await plugin.keep(ctx);
1092
- } catch (err) {
1093
- logPluginError(errorLogger, plugin.name, "keep", err);
1094
- }
1095
- }
1096
- }
1097
- };
1098
- }
1099
- var emptyRunner = createPluginRunner([]);
886
+ const errorLogger = options.logger ?? console;
887
+ const byName = /* @__PURE__ */ new Map();
888
+ for (const plugin of plugins) byName.set(plugin.name, plugin);
889
+ const list = Array.from(byName.values());
890
+ return {
891
+ plugins: list,
892
+ hasEnrich: list.some((p) => typeof p.enrich === "function"),
893
+ hasDrain: list.some((p) => typeof p.drain === "function"),
894
+ hasKeep: list.some((p) => typeof p.keep === "function"),
895
+ hasRequestLifecycle: list.some((p) => typeof p.onRequestStart === "function" || typeof p.onRequestFinish === "function"),
896
+ hasClientLog: list.some((p) => typeof p.onClientLog === "function"),
897
+ hasExtendLogger: list.some((p) => typeof p.extendLogger === "function"),
898
+ applyExtendLogger(logger) {
899
+ for (const plugin of list) {
900
+ if (!plugin.extendLogger) continue;
901
+ try {
902
+ plugin.extendLogger(logger);
903
+ } catch (err) {
904
+ logPluginError(errorLogger, plugin.name, "extendLogger", err);
905
+ }
906
+ }
907
+ },
908
+ runOnRequestStart(ctx) {
909
+ for (const plugin of list) {
910
+ if (!plugin.onRequestStart) continue;
911
+ try {
912
+ plugin.onRequestStart(ctx);
913
+ } catch (err) {
914
+ logPluginError(errorLogger, plugin.name, "onRequestStart", err);
915
+ }
916
+ }
917
+ },
918
+ runOnRequestFinish(ctx) {
919
+ for (const plugin of list) {
920
+ if (!plugin.onRequestFinish) continue;
921
+ try {
922
+ plugin.onRequestFinish(ctx);
923
+ } catch (err) {
924
+ logPluginError(errorLogger, plugin.name, "onRequestFinish", err);
925
+ }
926
+ }
927
+ },
928
+ runOnClientLog(ctx) {
929
+ for (const plugin of list) {
930
+ if (!plugin.onClientLog) continue;
931
+ try {
932
+ plugin.onClientLog(ctx);
933
+ } catch (err) {
934
+ logPluginError(errorLogger, plugin.name, "onClientLog", err);
935
+ }
936
+ }
937
+ },
938
+ async runSetup(ctx) {
939
+ for (const plugin of list) {
940
+ if (!plugin.setup) continue;
941
+ try {
942
+ await plugin.setup(ctx);
943
+ } catch (err) {
944
+ logPluginError(errorLogger, plugin.name, "setup", err);
945
+ }
946
+ }
947
+ },
948
+ async runEnrich(ctx) {
949
+ for (const plugin of list) {
950
+ if (!plugin.enrich) continue;
951
+ try {
952
+ await plugin.enrich(ctx);
953
+ } catch (err) {
954
+ logPluginError(errorLogger, plugin.name, "enrich", err);
955
+ }
956
+ }
957
+ },
958
+ async runDrain(ctx) {
959
+ const drains = list.filter((p) => typeof p.drain === "function");
960
+ if (drains.length === 0) return;
961
+ await Promise.allSettled(drains.map(async (plugin) => {
962
+ try {
963
+ await plugin.drain(ctx);
964
+ } catch (err) {
965
+ logPluginError(errorLogger, plugin.name, "drain", err);
966
+ }
967
+ }));
968
+ },
969
+ async runKeep(ctx) {
970
+ for (const plugin of list) {
971
+ if (!plugin.keep) continue;
972
+ try {
973
+ await plugin.keep(ctx);
974
+ } catch (err) {
975
+ logPluginError(errorLogger, plugin.name, "keep", err);
976
+ }
977
+ }
978
+ }
979
+ };
980
+ }
981
+ const emptyRunner = createPluginRunner([]);
1100
982
  function getEmptyPluginRunner() {
1101
- return emptyRunner;
983
+ return emptyRunner;
1102
984
  }
1103
985
 
1104
- // src/middleware-toolkit.ts
986
+ //#endregion
987
+ //#region src/middleware-toolkit.ts
1105
988
  function matchesRoutePattern(path, pattern) {
1106
- const regexPattern = pattern.replaceAll(/[.+^${}()|[\]\\]/g, String.raw`\$&`).replaceAll("**", "{{GLOBSTAR}}").replaceAll("*", "[^/]*").replaceAll("{{GLOBSTAR}}", ".*").replaceAll("?", "[^/]");
1107
- return new RegExp(`^${regexPattern}$`).test(path);
989
+ const regexPattern = pattern.replaceAll(/[.+^${}()|[\]\\]/g, String.raw`\$&`).replaceAll("**", "{{GLOBSTAR}}").replaceAll("*", "[^/]*").replaceAll("{{GLOBSTAR}}", ".*").replaceAll("?", "[^/]");
990
+ return new RegExp(`^${regexPattern}$`).test(path);
1108
991
  }
1109
992
  function shouldInstrumentPath(path, options = {}) {
1110
- const { include, exclude } = options;
1111
- if (exclude && exclude.some((pattern) => matchesRoutePattern(path, pattern))) {
1112
- return false;
1113
- }
1114
- if (!include || include.length === 0) {
1115
- return true;
1116
- }
1117
- return include.some((pattern) => matchesRoutePattern(path, pattern));
993
+ const { include, exclude } = options;
994
+ if (exclude && exclude.some((pattern) => matchesRoutePattern(path, pattern))) return false;
995
+ if (!include || include.length === 0) return true;
996
+ return include.some((pattern) => matchesRoutePattern(path, pattern));
1118
997
  }
1119
998
  function getServiceForPath(path, routes) {
1120
- if (!routes) return void 0;
1121
- for (const [pattern, config] of Object.entries(routes)) {
1122
- if (matchesRoutePattern(path, pattern)) {
1123
- return config.service;
1124
- }
1125
- }
1126
- return void 0;
999
+ if (!routes) return void 0;
1000
+ for (const [pattern, config] of Object.entries(routes)) if (matchesRoutePattern(path, pattern)) return config.service;
1127
1001
  }
1128
1002
  async function runMiddlewareFinishPipeline(ctx, options = {}) {
1129
- const logger = options.logger ?? console;
1130
- for (const enrich of options.enrichers ?? []) {
1131
- try {
1132
- await enrich(ctx);
1133
- } catch (err) {
1134
- logger.error("[autotel-edge/middleware] enricher failed:", err);
1135
- }
1136
- }
1137
- const drains = options.drains ?? [];
1138
- if (drains.length === 0) return;
1139
- await Promise.allSettled(
1140
- drains.map(async (drain) => {
1141
- try {
1142
- await drain(ctx);
1143
- } catch (err) {
1144
- logger.error("[autotel-edge/middleware] drain failed:", err);
1145
- }
1146
- })
1147
- );
1003
+ const logger = options.logger ?? console;
1004
+ for (const enrich of options.enrichers ?? []) try {
1005
+ await enrich(ctx);
1006
+ } catch (err) {
1007
+ logger.error("[autotel-edge/middleware] enricher failed:", err);
1008
+ }
1009
+ const drains = options.drains ?? [];
1010
+ if (drains.length === 0) return;
1011
+ await Promise.allSettled(drains.map(async (drain) => {
1012
+ try {
1013
+ await drain(ctx);
1014
+ } catch (err) {
1015
+ logger.error("[autotel-edge/middleware] drain failed:", err);
1016
+ }
1017
+ }));
1148
1018
  }
1149
1019
 
1150
- export { AsyncLocalStorageContextManager, SpanImpl, WorkerTracer, WorkerTracerProvider, composePostProcessors, composeSpanProcessors, composeSubscribers, createPluginRunner, defineConfig, definePlugin, getEmptyPluginRunner, getServiceForPath, instrument as instrumentFunctions, matchesRoutePattern, runMiddlewareFinishPipeline, shouldInstrumentPath, span, trace3 as trace, withNextSpan, withTracing };
1151
- //# sourceMappingURL=index.js.map
1020
+ //#endregion
1021
+ export { AsyncLocalStorageContextManager, Buffer, OTLPExporter, SpanImpl, WorkerTracer, WorkerTracerProvider, composePostProcessors, composeSpanProcessors, composeSubscribers, context, createInitialiser, createPluginRunner, defineConfig, definePlugin, getActiveConfig, getEmptyPluginRunner, getExecutionLogger, getServiceForPath, instrument as instrumentFunctions, matchesRoutePattern, parseConfig, parseError, propagation, runMiddlewareFinishPipeline, setConfig, shouldInstrumentPath, span, trace, withNextSpan, withTracing };
1152
1022
  //# sourceMappingURL=index.js.map