1+ import { AsyncLocalStorage } from "node:async_hooks" ;
12import { randomUUID } from "node:crypto" ;
23import { mkdirSync } from "node:fs" ;
34import { dirname } from "node:path" ;
@@ -60,8 +61,17 @@ type DiagnosticsTimelineOptions = {
6061 env ?: NodeJS . ProcessEnv ;
6162} ;
6263
64+ export type ActiveDiagnosticsTimelineSpan = {
65+ name : string ;
66+ phase ?: string ;
67+ spanId : string ;
68+ parentSpanId ?: string ;
69+ attributes ?: DiagnosticsTimelineAttributes ;
70+ } ;
71+
6372let warnedAboutTimelineWrite = false ;
6473const createdTimelineDirs = new Set < string > ( ) ;
74+ const activeDiagnosticsTimelineSpan = new AsyncLocalStorage < ActiveDiagnosticsTimelineSpan > ( ) ;
6575
6676function resolveDiagnosticsTimelineOptions (
6777 options : DiagnosticsTimelineOptions = { } ,
@@ -177,6 +187,10 @@ export function emitDiagnosticsTimelineEvent(
177187 }
178188}
179189
190+ export function getActiveDiagnosticsTimelineSpan ( ) : ActiveDiagnosticsTimelineSpan | undefined {
191+ return activeDiagnosticsTimelineSpan . getStore ( ) ;
192+ }
193+
180194export async function measureDiagnosticsTimelineSpan < T > (
181195 name : string ,
182196 run : ( ) => Promise < T > | T ,
@@ -186,28 +200,40 @@ export async function measureDiagnosticsTimelineSpan<T>(
186200 if ( ! isDiagnosticsTimelineEnabled ( { config : options . config , env } ) ) {
187201 return await run ( ) ;
188202 }
203+ const activeSpan = getActiveDiagnosticsTimelineSpan ( ) ;
189204 const spanId = randomUUID ( ) ;
205+ const phase = options . phase ?? activeSpan ?. phase ;
206+ const parentSpanId = options . parentSpanId ?? activeSpan ?. spanId ;
190207 const startedAt = performance . now ( ) ;
191208 emitDiagnosticsTimelineEvent (
192209 {
193210 type : "span.start" ,
194211 name,
195- phase : options . phase ,
212+ phase,
196213 spanId,
197- parentSpanId : options . parentSpanId ,
214+ parentSpanId,
198215 attributes : options . attributes ,
199216 } ,
200217 { config : options . config , env } ,
201218 ) ;
202219 try {
203- const result = await run ( ) ;
220+ const result = await activeDiagnosticsTimelineSpan . run (
221+ {
222+ name,
223+ ...( phase ? { phase } : { } ) ,
224+ spanId,
225+ ...( parentSpanId ? { parentSpanId } : { } ) ,
226+ ...( options . attributes ? { attributes : options . attributes } : { } ) ,
227+ } ,
228+ ( ) => run ( ) ,
229+ ) ;
204230 emitDiagnosticsTimelineEvent (
205231 {
206232 type : "span.end" ,
207233 name,
208- phase : options . phase ,
234+ phase,
209235 spanId,
210- parentSpanId : options . parentSpanId ,
236+ parentSpanId,
211237 durationMs : performance . now ( ) - startedAt ,
212238 attributes : options . attributes ,
213239 } ,
@@ -219,9 +245,9 @@ export async function measureDiagnosticsTimelineSpan<T>(
219245 {
220246 type : "span.error" ,
221247 name,
222- phase : options . phase ,
248+ phase,
223249 spanId,
224- parentSpanId : options . parentSpanId ,
250+ parentSpanId,
225251 durationMs : performance . now ( ) - startedAt ,
226252 attributes : options . attributes ,
227253 errorName : error instanceof Error ? error . name : typeof error ,
@@ -242,28 +268,40 @@ export function measureDiagnosticsTimelineSpanSync<T>(
242268 if ( ! isDiagnosticsTimelineEnabled ( { config : options . config , env } ) ) {
243269 return run ( ) ;
244270 }
271+ const activeSpan = getActiveDiagnosticsTimelineSpan ( ) ;
245272 const spanId = randomUUID ( ) ;
273+ const phase = options . phase ?? activeSpan ?. phase ;
274+ const parentSpanId = options . parentSpanId ?? activeSpan ?. spanId ;
246275 const startedAt = performance . now ( ) ;
247276 emitDiagnosticsTimelineEvent (
248277 {
249278 type : "span.start" ,
250279 name,
251- phase : options . phase ,
280+ phase,
252281 spanId,
253- parentSpanId : options . parentSpanId ,
282+ parentSpanId,
254283 attributes : options . attributes ,
255284 } ,
256285 { config : options . config , env } ,
257286 ) ;
258287 try {
259- const result = run ( ) ;
288+ const result = activeDiagnosticsTimelineSpan . run (
289+ {
290+ name,
291+ ...( phase ? { phase } : { } ) ,
292+ spanId,
293+ ...( parentSpanId ? { parentSpanId } : { } ) ,
294+ ...( options . attributes ? { attributes : options . attributes } : { } ) ,
295+ } ,
296+ run ,
297+ ) ;
260298 emitDiagnosticsTimelineEvent (
261299 {
262300 type : "span.end" ,
263301 name,
264- phase : options . phase ,
302+ phase,
265303 spanId,
266- parentSpanId : options . parentSpanId ,
304+ parentSpanId,
267305 durationMs : performance . now ( ) - startedAt ,
268306 attributes : options . attributes ,
269307 } ,
@@ -275,9 +313,9 @@ export function measureDiagnosticsTimelineSpanSync<T>(
275313 {
276314 type : "span.error" ,
277315 name,
278- phase : options . phase ,
316+ phase,
279317 spanId,
280- parentSpanId : options . parentSpanId ,
318+ parentSpanId,
281319 durationMs : performance . now ( ) - startedAt ,
282320 attributes : options . attributes ,
283321 errorName : error instanceof Error ? error . name : typeof error ,
0 commit comments