@dxos/tracing 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc

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 (48) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/index.mjs +331 -393
  3. package/dist/lib/browser/index.mjs.map +4 -4
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/node-esm/index.mjs +331 -393
  6. package/dist/lib/node-esm/index.mjs.map +4 -4
  7. package/dist/lib/node-esm/meta.json +1 -1
  8. package/dist/types/src/api.d.ts +36 -17
  9. package/dist/types/src/api.d.ts.map +1 -1
  10. package/dist/types/src/buffering-backend.d.ts +24 -0
  11. package/dist/types/src/buffering-backend.d.ts.map +1 -0
  12. package/dist/types/src/diagnostic.d.ts +2 -2
  13. package/dist/types/src/diagnostic.d.ts.map +1 -1
  14. package/dist/types/src/diagnostics-channel.d.ts.map +1 -1
  15. package/dist/types/src/index.d.ts +1 -2
  16. package/dist/types/src/index.d.ts.map +1 -1
  17. package/dist/types/src/metrics/base.d.ts.map +1 -1
  18. package/dist/types/src/metrics/custom-counter.d.ts.map +1 -1
  19. package/dist/types/src/metrics/map-counter.d.ts.map +1 -1
  20. package/dist/types/src/metrics/time-series-counter.d.ts.map +1 -1
  21. package/dist/types/src/metrics/time-usage-counter.d.ts.map +1 -1
  22. package/dist/types/src/metrics/unary-counter.d.ts.map +1 -1
  23. package/dist/types/src/remote/index.d.ts +0 -1
  24. package/dist/types/src/remote/index.d.ts.map +1 -1
  25. package/dist/types/src/remote/metrics.d.ts.map +1 -1
  26. package/dist/types/src/symbols.d.ts +0 -1
  27. package/dist/types/src/symbols.d.ts.map +1 -1
  28. package/dist/types/src/trace-processor.d.ts +16 -52
  29. package/dist/types/src/trace-processor.d.ts.map +1 -1
  30. package/dist/types/src/tracing-types.d.ts +67 -0
  31. package/dist/types/src/tracing-types.d.ts.map +1 -0
  32. package/dist/types/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +14 -13
  34. package/src/api.ts +237 -35
  35. package/src/buffering-backend.ts +112 -0
  36. package/src/diagnostic.ts +2 -2
  37. package/src/index.ts +1 -2
  38. package/src/remote/index.ts +0 -1
  39. package/src/symbols.ts +0 -2
  40. package/src/trace-processor.ts +58 -258
  41. package/src/tracing-types.ts +77 -0
  42. package/src/tracing.test.ts +513 -4
  43. package/dist/types/src/remote/tracing.d.ts +0 -23
  44. package/dist/types/src/remote/tracing.d.ts.map +0 -1
  45. package/dist/types/src/trace-sender.d.ts +0 -9
  46. package/dist/types/src/trace-sender.d.ts.map +0 -1
  47. package/src/remote/tracing.ts +0 -53
  48. package/src/trace-sender.ts +0 -88
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "@dxos/tracing",
3
- "version": "0.8.4-main.ae835ea",
3
+ "version": "0.8.4-main.bc2380dfbc",
4
4
  "description": "Async utilities.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
7
- "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
11
+ "license": "FSL-1.1-Apache-2.0",
8
12
  "author": "DXOS.org",
9
13
  "sideEffects": true,
10
14
  "type": "module",
@@ -19,22 +23,19 @@
19
23
  }
20
24
  },
21
25
  "types": "dist/types/src/index.d.ts",
22
- "typesVersions": {
23
- "*": {}
24
- },
25
26
  "files": [
26
27
  "dist",
27
28
  "src"
28
29
  ],
29
30
  "dependencies": {
30
- "@dxos/async": "0.8.4-main.ae835ea",
31
- "@dxos/context": "0.8.4-main.ae835ea",
32
- "@dxos/log": "0.8.4-main.ae835ea",
33
- "@dxos/node-std": "0.8.4-main.ae835ea",
34
- "@dxos/codec-protobuf": "0.8.4-main.ae835ea",
35
- "@dxos/protocols": "0.8.4-main.ae835ea",
36
- "@dxos/util": "0.8.4-main.ae835ea",
37
- "@dxos/invariant": "0.8.4-main.ae835ea"
31
+ "@dxos/codec-protobuf": "0.8.4-main.bc2380dfbc",
32
+ "@dxos/async": "0.8.4-main.bc2380dfbc",
33
+ "@dxos/context": "0.8.4-main.bc2380dfbc",
34
+ "@dxos/log": "0.8.4-main.bc2380dfbc",
35
+ "@dxos/invariant": "0.8.4-main.bc2380dfbc",
36
+ "@dxos/node-std": "0.8.4-main.bc2380dfbc",
37
+ "@dxos/protocols": "0.8.4-main.bc2380dfbc",
38
+ "@dxos/util": "0.8.4-main.bc2380dfbc"
38
39
  },
39
40
  "publishConfig": {
40
41
  "access": "public"
package/src/api.ts CHANGED
@@ -2,19 +2,66 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { Context } from '@dxos/context';
5
+ import { Context, LifecycleState, Resource, TRACE_SPAN_ATTRIBUTE } from '@dxos/context';
6
6
  import { type MaybePromise } from '@dxos/util';
7
7
 
8
8
  import { getTracingContext } from './symbols';
9
- import { TRACE_PROCESSOR, type TraceSpanParams, type TracingSpan } from './trace-processor';
9
+ import { TRACE_PROCESSOR, sanitizeClassName } from './trace-processor';
10
+ import type { RemoteSpan } from './tracing-types';
11
+
12
+ const LIFECYCLE_SPAN = Symbol('dxos.tracing.lifecycle-span');
13
+
14
+ /** localStorage key that switches the browser OTEL sampler from 30% to 100%. */
15
+ export const TRACE_ALL_KEY = 'dxos.debug.traceAll';
16
+
17
+ /**
18
+ * Reads `@trace.info({ spanAttribute: true })` properties from the instance
19
+ * and writes them into the span attributes map.
20
+ */
21
+ const collectSpanAttributes = (instance: any, spanAttributes: Record<string, any>) => {
22
+ const proto = Object.getPrototypeOf(instance);
23
+ if (!proto) {
24
+ return;
25
+ }
26
+ const tracingContext = getTracingContext(proto);
27
+ for (const [key, { options }] of Object.entries(tracingContext.infoProperties)) {
28
+ if (!options.spanAttribute) {
29
+ continue;
30
+ }
31
+ try {
32
+ const value = typeof instance[key] === 'function' ? instance[key]() : instance[key];
33
+ if (value != null) {
34
+ const resolved = options.enum ? options.enum[value] : String(value);
35
+ spanAttributes[`ctx.${key}`] = resolved;
36
+ }
37
+ } catch {
38
+ // Skip properties that throw (e.g. uninitialized).
39
+ }
40
+ }
41
+ };
42
+
43
+ export type ResourceOptions = {
44
+ annotation?: symbol;
45
+ /**
46
+ * Start a lifecycle span on `open()` and end it on `close()`.
47
+ * `this._ctx` carries the lifecycle span's trace context, so background work
48
+ * (subscriptions, timers) becomes children of the lifecycle span.
49
+ * Direct calls within `_open` use the `_open` span's context as usual.
50
+ * Requires the class to extend {@link Resource}.
51
+ */
52
+ lifecycle?: boolean;
53
+ };
10
54
 
11
55
  /**
12
56
  * Annotates a class as a tracked resource.
13
57
  */
14
58
  const resource =
15
- (options?: { annotation?: symbol }) =>
59
+ (options?: ResourceOptions) =>
16
60
  <T extends { new (...args: any[]): {} }>(constructor: T) => {
17
- // Wrapping class declaration into an IIFE so it doesn't capture the `klass` class name.
61
+ if (options?.lifecycle && !(constructor.prototype instanceof Resource)) {
62
+ throw new Error(`@trace.resource({ lifecycle: true }) requires ${constructor.name} to extend Resource`);
63
+ }
64
+
18
65
  const klass = (() =>
19
66
  class extends constructor {
20
67
  constructor(...rest: any[]) {
@@ -22,6 +69,68 @@ const resource =
22
69
  TRACE_PROCESSOR.createTraceResource({ constructor, annotation: options?.annotation, instance: this });
23
70
  }
24
71
  })();
72
+
73
+ if (options?.lifecycle) {
74
+ const sanitizedName = sanitizeClassName(constructor.name);
75
+ const proto = klass.prototype as any;
76
+ const originalOpen = proto.open;
77
+ const originalClose = proto.close;
78
+
79
+ proto.open = async function (ctx?: Context): Promise<any> {
80
+ const self = this as any;
81
+
82
+ if (self._lifecycleState !== LifecycleState.CLOSED) {
83
+ return originalOpen.call(this, ctx);
84
+ }
85
+
86
+ const parentSpanContext = ctx?.getAttribute(TRACE_SPAN_ATTRIBUTE);
87
+ const resourceEntry = TRACE_PROCESSOR.resourceInstanceIndex.get(this);
88
+ const spanAttributes: Record<string, any> = {};
89
+ if (resourceEntry) {
90
+ spanAttributes.entryPoint = resourceEntry.sanitizedClassName;
91
+ }
92
+
93
+ const remoteSpan = TRACE_PROCESSOR.tracingBackend?.startSpan({
94
+ name: `${sanitizedName}.lifecycle`,
95
+ op: 'lifecycle',
96
+ attributes: spanAttributes,
97
+ parentContext: parentSpanContext,
98
+ });
99
+ self[LIFECYCLE_SPAN] = remoteSpan;
100
+
101
+ let openCtx = ctx;
102
+ if (remoteSpan?.spanContext != null) {
103
+ const traceAttrs = { [TRACE_SPAN_ATTRIBUTE]: remoteSpan.spanContext };
104
+ openCtx = ctx ? ctx.derive({ attributes: traceAttrs }) : new Context({ attributes: traceAttrs });
105
+ }
106
+
107
+ try {
108
+ return await originalOpen.call(this, openCtx);
109
+ } catch (err) {
110
+ remoteSpan?.setError?.(err);
111
+ remoteSpan?.end();
112
+ self[LIFECYCLE_SPAN] = undefined;
113
+ throw err;
114
+ }
115
+ };
116
+
117
+ proto.close = async function (ctx?: Context): Promise<any> {
118
+ const self = this as any;
119
+ const remoteSpan: RemoteSpan | undefined = self[LIFECYCLE_SPAN];
120
+ try {
121
+ return await originalClose.call(this, ctx);
122
+ } catch (err) {
123
+ remoteSpan?.setError?.(err);
124
+ throw err;
125
+ } finally {
126
+ if (remoteSpan) {
127
+ remoteSpan.end();
128
+ self[LIFECYCLE_SPAN] = undefined;
129
+ }
130
+ }
131
+ };
132
+ }
133
+
25
134
  Object.defineProperty(klass, 'name', { value: constructor.name });
26
135
  return klass;
27
136
  };
@@ -51,6 +160,9 @@ export type InfoOptions = {
51
160
  * Default: 0 - objects will be stringified with toString.
52
161
  */
53
162
  depth?: number | null;
163
+
164
+ /** When true, the property value is also set as an OTEL span attribute on every span created by this resource. */
165
+ spanAttribute?: boolean;
54
166
  };
55
167
 
56
168
  /**
@@ -68,63 +180,157 @@ const mark = (name: string) => {
68
180
 
69
181
  export type SpanOptions = {
70
182
  showInBrowserTimeline?: boolean;
183
+ /** When false the span is not exported to remote OTLP collectors. Defaults to true. */
184
+ showInRemoteTracing?: boolean;
71
185
  op?: string;
72
186
  attributes?: Record<string, any>;
73
187
  };
74
188
 
75
189
  /**
76
190
  * Decorator that creates a span for the execution duration of the decorated method.
191
+ * Calls the TracingBackend directly; no custom TracingSpan objects.
77
192
  */
78
193
  const span =
79
- ({ showInBrowserTimeline = false, op, attributes }: SpanOptions = {}) =>
194
+ ({ showInBrowserTimeline = false, showInRemoteTracing = true, op, attributes }: SpanOptions = {}) =>
80
195
  (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any) => any>) => {
81
196
  const method = descriptor.value!;
82
197
 
83
198
  descriptor.value = async function (this: any, ...args: any) {
84
199
  const parentCtx = args[0] instanceof Context ? args[0] : null;
85
- const span = TRACE_PROCESSOR.traceSpan({
86
- parentCtx,
87
- methodName: propertyKey,
88
- instance: this,
89
- showInBrowserTimeline,
90
- op,
91
- attributes,
92
- });
93
-
94
- const callArgs = span.ctx ? [span.ctx, ...args.slice(1)] : args;
200
+ const startTs = performance.now();
201
+
202
+ const parentSpanContext = parentCtx?.getAttribute(TRACE_SPAN_ATTRIBUTE);
203
+
204
+ const resourceEntry = TRACE_PROCESSOR.resourceInstanceIndex.get(this);
205
+ const className = resourceEntry?.sanitizedClassName ?? sanitizeClassName(target.constructor?.name ?? 'unknown');
206
+ const spanName = `${className}.${propertyKey}`;
207
+
208
+ const spanAttributes: Record<string, any> = {};
209
+ if (resourceEntry) {
210
+ spanAttributes.entryPoint = resourceEntry.sanitizedClassName;
211
+ }
212
+ collectSpanAttributes(this, spanAttributes);
213
+ if (attributes) {
214
+ for (const [key, value] of Object.entries(attributes)) {
215
+ spanAttributes[key.startsWith('ctx.') ? key : `ctx.${key}`] = value;
216
+ }
217
+ }
218
+
219
+ const remoteSpan = showInRemoteTracing
220
+ ? TRACE_PROCESSOR.tracingBackend?.startSpan({
221
+ name: spanName,
222
+ op: op ?? 'function',
223
+ attributes: spanAttributes,
224
+ parentContext: parentSpanContext,
225
+ })
226
+ : undefined;
227
+
228
+ let callArgs = args;
229
+ if (parentCtx) {
230
+ const childCtx =
231
+ remoteSpan?.spanContext != null
232
+ ? parentCtx.derive({ attributes: { [TRACE_SPAN_ATTRIBUTE]: remoteSpan.spanContext } })
233
+ : parentCtx.derive();
234
+ callArgs = [childCtx, ...args.slice(1)];
235
+ }
236
+
95
237
  try {
96
238
  return await method.apply(this, callArgs);
97
239
  } catch (err) {
98
- span.markError(err);
240
+ remoteSpan?.setError?.(err);
99
241
  throw err;
100
242
  } finally {
101
- span.markSuccess();
243
+ remoteSpan?.end();
244
+ if (showInBrowserTimeline && typeof globalThis?.performance?.measure === 'function') {
245
+ performance.measure(spanName, { start: startTs, end: performance.now() });
246
+ }
102
247
  }
103
248
  };
104
249
  };
105
250
 
106
- const spans = new Map<string, TracingSpan>();
251
+ const manualSpans = new Map<string, RemoteSpan>();
252
+ const manualSpanTimestamps = new Map<string, { name: string; startTs: number }>();
253
+
254
+ export type ManualSpanParams = {
255
+ id: string;
256
+ instance: any;
257
+ methodName: string;
258
+ parentCtx: Context | null;
259
+ showInBrowserTimeline?: boolean;
260
+ showInRemoteTracing?: boolean;
261
+ op?: string;
262
+ attributes?: Record<string, any>;
263
+ };
107
264
 
108
265
  /**
109
266
  * Creates a span that must be ended manually.
267
+ *
268
+ * Returns a child Context that carries the new span's `TRACE_SPAN_ATTRIBUTE`.
269
+ * Callers should use the returned ctx for downstream work so that nested
270
+ * `@trace.span` methods and RPC calls inherit this span as their parent
271
+ * and land in the same trace (rather than starting a new root).
272
+ *
273
+ * When the new span cannot be created (duplicate id, no backend, or
274
+ * `showInRemoteTracing: false`), the parentCtx is returned unchanged.
110
275
  */
111
- const spanStart = (params: TraceSpanParams & { id: string }) => {
112
- if (spans.has(params.id)) {
113
- return;
276
+ const spanStart = (params: ManualSpanParams): Context | null => {
277
+ if (manualSpans.has(params.id) || manualSpanTimestamps.has(params.id)) {
278
+ return params.parentCtx;
279
+ }
280
+
281
+ const resourceEntry = TRACE_PROCESSOR.resourceInstanceIndex.get(params.instance);
282
+ const className = resourceEntry?.sanitizedClassName ?? 'unknown';
283
+ const spanName = `${className}.${params.methodName}`;
284
+
285
+ if (params.showInBrowserTimeline) {
286
+ manualSpanTimestamps.set(params.id, { name: spanName, startTs: performance.now() });
287
+ }
288
+
289
+ if (params.showInRemoteTracing === false || !TRACE_PROCESSOR.tracingBackend) {
290
+ return params.parentCtx;
291
+ }
292
+
293
+ const parentSpanContext = params.parentCtx?.getAttribute(TRACE_SPAN_ATTRIBUTE);
294
+
295
+ const spanAttributes: Record<string, any> = {};
296
+ if (resourceEntry) {
297
+ spanAttributes.entryPoint = resourceEntry.sanitizedClassName;
298
+ }
299
+ collectSpanAttributes(params.instance, spanAttributes);
300
+ if (params.attributes) {
301
+ for (const [key, value] of Object.entries(params.attributes)) {
302
+ spanAttributes[key.startsWith('ctx.') ? key : `ctx.${key}`] = value;
303
+ }
114
304
  }
115
305
 
116
- const span = TRACE_PROCESSOR.traceSpan(params);
117
- spans.set(params.id, span);
306
+ const remoteSpan = TRACE_PROCESSOR.tracingBackend.startSpan({
307
+ name: spanName,
308
+ op: params.op ?? 'function',
309
+ attributes: spanAttributes,
310
+ parentContext: parentSpanContext,
311
+ });
312
+ manualSpans.set(params.id, remoteSpan);
313
+
314
+ if (params.parentCtx && remoteSpan.spanContext != null) {
315
+ return params.parentCtx.derive({ attributes: { [TRACE_SPAN_ATTRIBUTE]: remoteSpan.spanContext } });
316
+ }
317
+ return params.parentCtx;
118
318
  };
119
319
 
120
320
  /**
121
321
  * Ends a span that was started manually.
122
322
  */
123
323
  const spanEnd = (id: string) => {
124
- const span = spans.get(id);
125
- if (span) {
126
- span.markSuccess();
127
- spans.delete(id);
324
+ const remoteSpan = manualSpans.get(id);
325
+ if (remoteSpan) {
326
+ remoteSpan.end();
327
+ manualSpans.delete(id);
328
+ }
329
+
330
+ const timestamps = manualSpanTimestamps.get(id);
331
+ if (timestamps && typeof globalThis?.performance?.measure === 'function') {
332
+ performance.measure(timestamps.name, { start: timestamps.startTs, end: performance.now() });
333
+ manualSpanTimestamps.delete(id);
128
334
  }
129
335
  };
130
336
 
@@ -141,10 +347,8 @@ const addLink = (parent: any, child: any, opts: AddLinkOptions = {}) => {
141
347
  TRACE_PROCESSOR.addLink(parent, child, opts);
142
348
  };
143
349
 
144
- export type TraceDiagnosticParams<T> = {
145
- /**
146
- * Unique ID.
147
- */
350
+ export type TraceDiagnosticProps<T> = {
351
+ /** Unique ID. */
148
352
  id: string;
149
353
 
150
354
  /**
@@ -153,9 +357,7 @@ export type TraceDiagnosticParams<T> = {
153
357
  */
154
358
  name?: string;
155
359
 
156
- /**
157
- * Function that will be called to fetch the diagnostic data.
158
- */
360
+ /** Function that will be called to fetch the diagnostic data. */
159
361
  fetch: () => MaybePromise<T>;
160
362
  };
161
363
 
@@ -167,7 +369,7 @@ export interface TraceDiagnostic {
167
369
  /**
168
370
  * Register a diagnostic that could be queried.
169
371
  */
170
- const diagnostic = <T>(params: TraceDiagnosticParams<T>): TraceDiagnostic => {
372
+ const diagnostic = <T>(params: TraceDiagnosticProps<T>): TraceDiagnostic => {
171
373
  return TRACE_PROCESSOR.diagnostics.registerDiagnostic(params);
172
374
  };
173
375
 
@@ -0,0 +1,112 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { type TraceContextData } from '@dxos/context';
6
+
7
+ import type { RemoteSpan, StartSpanOptions, TracingBackend } from './tracing-types';
8
+
9
+ export const BUFFERED_PREFIX = 'buffered-';
10
+
11
+ /**
12
+ * Span handle that records operations while no real OTEL backend is available.
13
+ * Once a real backend is registered, the buffered span is replayed and a
14
+ * {@link delegate} is set so future calls forward to the real span.
15
+ */
16
+ class BufferedSpan implements RemoteSpan {
17
+ readonly spanContext: TraceContextData;
18
+ readonly startTime: number;
19
+ delegate?: RemoteSpan;
20
+
21
+ #ended = false;
22
+ #endTime?: number;
23
+ #error?: unknown;
24
+ #hasError = false;
25
+
26
+ constructor(
27
+ readonly options: StartSpanOptions,
28
+ id: number,
29
+ ) {
30
+ this.spanContext = { traceparent: `${BUFFERED_PREFIX}${id}` };
31
+ this.startTime = Date.now();
32
+ }
33
+
34
+ end(endTime?: number): void {
35
+ if (this.delegate) {
36
+ this.delegate.end(endTime);
37
+ return;
38
+ }
39
+ this.#endTime = endTime ?? Date.now();
40
+ this.#ended = true;
41
+ }
42
+
43
+ setError(err: unknown): void {
44
+ if (this.delegate) {
45
+ this.delegate.setError?.(err);
46
+ return;
47
+ }
48
+ this.#error = err;
49
+ this.#hasError = true;
50
+ }
51
+
52
+ replay(real: RemoteSpan): void {
53
+ if (this.#hasError) {
54
+ real.setError?.(this.#error);
55
+ }
56
+ if (this.#ended) {
57
+ real.end(this.#endTime);
58
+ } else {
59
+ this.delegate = real;
60
+ }
61
+ }
62
+ }
63
+
64
+ /**
65
+ * A {@link TracingBackend} that buffers span operations until a real backend
66
+ * registers. On {@link drain}, buffered spans are replayed in FIFO order with
67
+ * parent IDs translated from synthetic `buffered-*` traceparents to real OTEL
68
+ * IDs, preserving the trace hierarchy.
69
+ */
70
+ export class BufferingTracingBackend implements TracingBackend {
71
+ readonly #pending: BufferedSpan[] = [];
72
+ #counter = 0;
73
+
74
+ startSpan(options: StartSpanOptions): RemoteSpan {
75
+ const span = new BufferedSpan(options, ++this.#counter);
76
+ this.#pending.push(span);
77
+ return span;
78
+ }
79
+
80
+ /** Discard all buffered spans without replaying them. */
81
+ clear(): void {
82
+ this.#pending.length = 0;
83
+ }
84
+
85
+ /**
86
+ * Replay all buffered spans into {@link backend}.
87
+ *
88
+ * @returns Map from synthetic buffered traceparent to real {@link TraceContextData},
89
+ * used by the post-drain translating wrapper to resolve stale buffered IDs
90
+ * still present on in-flight {@link Context} objects.
91
+ */
92
+ drain(backend: TracingBackend): Map<string, TraceContextData> {
93
+ const idMap = new Map<string, TraceContextData>();
94
+
95
+ for (const buffered of this.#pending) {
96
+ let parentContext = buffered.options.parentContext;
97
+ if (parentContext && parentContext.traceparent.startsWith(BUFFERED_PREFIX)) {
98
+ parentContext = idMap.get(parentContext.traceparent) ?? parentContext;
99
+ }
100
+
101
+ const real = backend.startSpan({ ...buffered.options, parentContext, startTime: buffered.startTime });
102
+
103
+ if (real.spanContext) {
104
+ idMap.set(buffered.spanContext.traceparent, real.spanContext);
105
+ }
106
+
107
+ buffered.replay(real);
108
+ }
109
+ this.#pending.length = 0;
110
+ return idMap;
111
+ }
112
+ }
package/src/diagnostic.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  import { asyncTimeout } from '@dxos/async';
6
6
  import { invariant } from '@dxos/invariant';
7
7
 
8
- import { type TraceDiagnostic, type TraceDiagnosticParams } from './api';
8
+ import { type TraceDiagnostic, type TraceDiagnosticProps } from './api';
9
9
  import { createId } from './util';
10
10
 
11
11
  export const DIAGNOSTICS_TIMEOUT = 10_000;
@@ -58,7 +58,7 @@ export class DiagnosticsManager {
58
58
  this._instanceTag = tag;
59
59
  }
60
60
 
61
- registerDiagnostic(params: TraceDiagnosticParams<any>): TraceDiagnostic {
61
+ registerDiagnostic(params: TraceDiagnosticProps<any>): TraceDiagnostic {
62
62
  const impl = new TraceDiagnosticImpl(params.id, params.fetch, params.name ?? params.id, () => {
63
63
  if (this.registry.get(params.id) === impl) {
64
64
  this.registry.delete(params.id);
package/src/index.ts CHANGED
@@ -7,11 +7,10 @@ import { trace } from './api';
7
7
  export * from './api';
8
8
  export * from './symbols';
9
9
  export * from './trace-processor';
10
- export * from './trace-sender';
10
+ export * from './tracing-types';
11
11
  export * from './metrics';
12
12
  export * from './diagnostic';
13
13
  export * from './diagnostics-channel';
14
- export * from './remote/tracing';
15
14
  export * from './remote/metrics';
16
15
 
17
16
  trace.diagnostic({
@@ -3,4 +3,3 @@
3
3
  //
4
4
 
5
5
  export * from './metrics';
6
- export * from './tracing';
package/src/symbols.ts CHANGED
@@ -22,5 +22,3 @@ export const getTracingContext = (target: any): TracingContext => {
22
22
  metricsProperties: {},
23
23
  });
24
24
  };
25
-
26
- export const TRACE_SPAN_ATTRIBUTE = 'dxos.trace-span';