@code-pushup/utils 0.113.0 → 0.113.1

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.
@@ -1,6 +1,5 @@
1
1
  import type { PerformanceEntry, PerformanceMark, PerformanceMeasure } from 'node:perf_hooks';
2
- import type { UserTimingDetail } from '../user-timing-extensibility-api.type.js';
3
- import type { BeginEvent, CompleteEvent, EndEvent, InstantEvent, InstantEventArgs, InstantEventTracingStartedInBrowser, SpanEventArgs, TraceEvent, TraceEventContainer, TraceEventRaw, TraceMetadata, UserTimingTraceEvent } from './trace-file.type.js';
2
+ import type { TraceEvent, TraceEventContainer, TraceMetadata, TracingStartedInBrowserOptions } from './trace-file.type.js';
4
3
  /**
5
4
  * Generates a unique ID for linking begin and end span events in Chrome traces.
6
5
  * @returns Object with local ID string for the id2 field
@@ -9,175 +8,125 @@ export declare const nextId2: () => {
9
8
  local: string;
10
9
  };
11
10
  /**
12
- * Generates a unique frame tree node ID from process and thread IDs.
11
+ * Generates a frame tree node ID from process and thread IDs.
13
12
  * @param pid - Process ID
14
13
  * @param tid - Thread ID
15
- * @returns Combined numeric ID
14
+ * @returns Frame tree node ID as a number
16
15
  */
17
16
  export declare const frameTreeNodeId: (pid: number, tid: number) => number;
18
17
  /**
19
- * Generates a frame name string from process and thread IDs.
18
+ * Generates a frame name from process and thread IDs.
20
19
  * @param pid - Process ID
21
20
  * @param tid - Thread ID
22
- * @returns Formatted frame name
21
+ * @returns Frame name string in format FRAME0P{pid}T{tid}
23
22
  */
24
23
  export declare const frameName: (pid: number, tid: number) => string;
25
24
  /**
26
25
  * Creates an instant trace event for marking a point in time.
27
- * @param opt - Event configuration options
28
- * @returns InstantEvent object
26
+ * @param name - Event name
27
+ * @param ts - Optional timestamp in microseconds
28
+ * @param opt - Optional event configuration
29
+ * @returns Instant trace event (ph: 'I')
29
30
  */
30
- export declare const getInstantEvent: (opt: {
31
- name: string;
32
- ts?: number;
33
- pid?: number;
34
- tid?: number;
35
- args?: InstantEventArgs;
36
- }) => InstantEvent;
31
+ export declare const instant: (name: string, ts?: number, opt?: Partial<TraceEvent>) => TraceEvent;
32
+ /**
33
+ * Creates a pair of begin and end span events.
34
+ * @param name - Span name
35
+ * @param tsB - Begin timestamp in microseconds
36
+ * @param tsE - End timestamp in microseconds
37
+ * @param opt - Optional event configuration
38
+ * @param opt.tsMarkerPadding - Padding to apply to timestamps (default: 1)
39
+ * @returns Array of [begin event, end event]
40
+ */
41
+ export declare const span: (name: string, tsB: number, tsE: number, opt?: Partial<TraceEvent> & {
42
+ tsMarkerPadding?: number;
43
+ }) => TraceEvent[];
37
44
  /**
38
45
  * Creates a start tracing event with frame information.
39
46
  * This event is needed at the beginning of the traceEvents array to make tell the UI profiling has started, and it should visualize the data.
40
47
  * @param opt - Tracing configuration options
41
48
  * @returns StartTracingEvent object
42
49
  */
43
- export declare const getInstantEventTracingStartedInBrowser: (opt: {
44
- url: string;
45
- ts?: number;
46
- pid?: number;
47
- tid?: number;
48
- }) => InstantEventTracingStartedInBrowser;
50
+ export declare const getInstantEventTracingStartedInBrowser: (opt: TracingStartedInBrowserOptions) => TraceEvent;
49
51
  /**
50
52
  * Creates a complete trace event with duration.
51
- * @param opt - Event configuration with name and duration
52
- * @returns CompleteEvent object
53
+ * @param name - Event name
54
+ * @param dur - Duration in microseconds
55
+ * @param opt - Optional event configuration
56
+ * @returns Complete trace event (ph: 'X')
53
57
  */
54
- export declare const getCompleteEvent: (opt: {
55
- name: string;
56
- dur: number;
57
- ts?: number;
58
- pid?: number;
59
- tid?: number;
60
- }) => CompleteEvent;
61
- /** Options for creating span events */
62
- type SpanOpt = {
63
- name: string;
64
- id2: {
65
- local: string;
66
- };
67
- ts?: number;
68
- pid?: number;
69
- tid?: number;
70
- args?: SpanEventArgs;
71
- };
72
- /**
73
- * Creates a begin span event.
74
- * @param ph - Phase ('b' for begin)
75
- * @param opt - Span event options
76
- * @returns BeginEvent object
77
- */
78
- export declare function getSpanEvent(ph: 'b', opt: SpanOpt): BeginEvent;
79
- /**
80
- * Creates an end span event.
81
- * @param ph - Phase ('e' for end)
82
- * @param opt - Span event options
83
- * @returns EndEvent object
84
- */
85
- export declare function getSpanEvent(ph: 'e', opt: SpanOpt): EndEvent;
86
- /**
87
- * Creates a pair of begin and end span events.
88
- * @param opt - Span configuration with start/end timestamps
89
- * @returns Tuple of BeginEvent and EndEvent
90
- */
91
- export declare const getSpan: (opt: {
92
- name: string;
93
- tsB: number;
94
- tsE: number;
95
- id2?: {
96
- local: string;
97
- };
98
- pid?: number;
99
- tid?: number;
100
- args?: SpanEventArgs;
101
- tsMarkerPadding?: number;
102
- }) => [BeginEvent, EndEvent];
58
+ export declare const complete: (name: string, dur: number, opt?: Partial<TraceEvent>) => TraceEvent;
103
59
  /**
104
60
  * Converts a PerformanceMark to an instant trace event.
105
61
  * @param entry - Performance mark entry
106
62
  * @param opt - Optional overrides for name, pid, and tid
107
- * @returns InstantEvent object
63
+ * @returns Instant trace event
108
64
  */
109
65
  export declare const markToInstantEvent: (entry: PerformanceMark, opt?: {
110
66
  name?: string;
111
67
  pid?: number;
112
68
  tid?: number;
113
- }) => InstantEvent;
69
+ }) => TraceEvent;
114
70
  /**
115
71
  * Converts a PerformanceMeasure to a pair of span events.
116
72
  * @param entry - Performance measure entry
117
73
  * @param opt - Optional overrides for name, pid, and tid
118
- * @returns Tuple of BeginEvent and EndEvent
74
+ * @returns Array of [begin event, end event]
119
75
  */
120
76
  export declare const measureToSpanEvents: (entry: PerformanceMeasure, opt?: {
121
77
  name?: string;
122
78
  pid?: number;
123
79
  tid?: number;
124
- }) => [BeginEvent, EndEvent];
80
+ }) => TraceEvent[];
125
81
  /**
126
- * Converts a PerformanceEntry to an array of UserTimingTraceEvents.
82
+ * Converts a PerformanceEntry to an array of trace events.
127
83
  * A mark is converted to an instant event, and a measure is converted to a pair of span events.
128
84
  * Other entry types are ignored.
129
85
  * @param entry - Performance entry
130
- * @returns UserTimingTraceEvent[]
86
+ * @returns Array of trace events
87
+ */
88
+ export declare function entryToTraceEvents(entry: PerformanceEntry): TraceEvent[];
89
+ /**
90
+ * Encodes a trace event by converting object details to JSON strings.
91
+ * @param e - Trace event with potentially object details
92
+ * @returns Trace event with string-encoded details
93
+ */
94
+ export declare const encodeEvent: (e: TraceEvent) => TraceEvent;
95
+ /**
96
+ * Decodes a trace event by parsing JSON string details back to objects.
97
+ * @param e - Trace event with potentially string-encoded details
98
+ * @returns Trace event with decoded object details
99
+ */
100
+ export declare const decodeEvent: (e: TraceEvent) => TraceEvent;
101
+ /**
102
+ * Serializes a trace event to a JSON string for storage.
103
+ * First encodes the event structure (converting object details to JSON strings),
104
+ * then stringifies the entire event.
105
+ * @param event - Trace event to serialize
106
+ * @returns JSON string representation of the encoded trace event
107
+ */
108
+ export declare const serializeTraceEvent: (event: TraceEvent) => string;
109
+ /**
110
+ * Deserializes a JSON string back to a trace event.
111
+ * First parses the JSON string, then decodes the event structure
112
+ * (parsing JSON string details back to objects).
113
+ * @param json - JSON string representation of a trace event
114
+ * @returns Decoded trace event
131
115
  */
132
- export declare function entryToTraceEvents(entry: PerformanceEntry): UserTimingTraceEvent[];
116
+ export declare const deserializeTraceEvent: (json: string) => TraceEvent;
133
117
  /**
134
118
  * Creates trace metadata object with standard DevTools fields and custom metadata.
135
119
  * @param startDate - Optional start date for the trace, defaults to current date
136
120
  * @param metadata - Optional additional metadata to merge into the trace metadata
137
121
  * @returns TraceMetadata object with source, startTime, and merged custom metadata
138
122
  */
139
- export declare function getTraceMetadata(startDate?: Date, metadata?: Record<string, unknown>): {
140
- source: string;
141
- startTime: string;
142
- hardwareConcurrency: number;
143
- dataOrigin: string;
144
- };
123
+ export declare function getTraceMetadata({ startDate, ...metadata }?: Partial<TraceMetadata>): TraceMetadata;
145
124
  /**
146
125
  * Creates a complete trace file container with metadata.
147
126
  * @param opt - Trace file configuration
148
127
  * @returns TraceEventContainer with events and metadata
149
128
  */
150
- export declare const getTraceFile: (opt: {
129
+ export declare const createTraceFile: (opt: {
151
130
  traceEvents: TraceEvent[];
152
- startTime?: string;
153
131
  metadata?: Partial<TraceMetadata>;
154
132
  }) => TraceEventContainer;
155
- /**
156
- * Decodes a JSON string detail property back to its original object form.
157
- * @param target - Object containing a detail property as a JSON string
158
- * @returns UserTimingDetail with the detail property parsed from JSON
159
- */
160
- export declare function decodeDetail(target: {
161
- detail: string;
162
- }): UserTimingDetail;
163
- /**
164
- * Encodes object detail properties to JSON strings for storage/transmission.
165
- * @param target - UserTimingDetail object with detail property to encode
166
- * @returns UserTimingDetail with object details converted to JSON strings
167
- */
168
- export declare function encodeDetail(target: UserTimingDetail): UserTimingDetail;
169
- /**
170
- * Decodes a raw trace event with JSON string details back to typed UserTimingTraceEvent.
171
- * Parses detail properties from JSON strings to objects.
172
- * @param event - Raw trace event with string-encoded details
173
- * @returns UserTimingTraceEvent with parsed detail objects
174
- */
175
- export declare function decodeTraceEvent({ args, ...rest }: TraceEventRaw): UserTimingTraceEvent;
176
- /**
177
- * Encodes a UserTimingTraceEvent to raw format with JSON string details.
178
- * Converts object details to JSON strings for storage/transmission.
179
- * @param event - UserTimingTraceEvent with object details
180
- * @returns TraceEventRaw with string-encoded details
181
- */
182
- export declare function encodeTraceEvent({ args, ...rest }: UserTimingTraceEvent): TraceEventRaw;
183
- export {};
@@ -1,6 +1,11 @@
1
+ import os from 'node:os';
1
2
  import { threadId } from 'node:worker_threads';
2
3
  import { defaultClock } from '../clock-epoch.js';
3
- /** Global counter for generating unique span IDs within a trace */
4
+ /**
5
+ * Trace-local monotonic span id counter.
6
+ * Chrome only requires uniqueness within a single trace file.
7
+ * Resetting per trace is intentional - we're not aiming for global uniqueness.
8
+ */
4
9
  // eslint-disable-next-line functional/no-let
5
10
  let id2Count = 0;
6
11
  /**
@@ -9,44 +14,58 @@ let id2Count = 0;
9
14
  */
10
15
  export const nextId2 = () => ({ local: `0x${++id2Count}` });
11
16
  /**
12
- * Provides default values for trace event properties.
13
- * @param opt - Optional overrides for process ID, thread ID, and timestamp
14
- * @param opt.pid - Process ID override, defaults to current process PID
15
- * @param opt.tid - Thread ID override, defaults to current thread ID
16
- * @param opt.ts - Timestamp override in microseconds, defaults to current epoch time
17
- * @returns Object containing pid, tid, and ts with defaults applied
18
- */
19
- const defaults = (opt) => ({
20
- pid: opt?.pid ?? process.pid,
21
- tid: opt?.tid ?? threadId,
22
- ts: opt?.ts ?? defaultClock.epochNowUs(),
23
- });
24
- /**
25
- * Generates a unique frame tree node ID from process and thread IDs.
17
+ * Generates a frame tree node ID from process and thread IDs.
26
18
  * @param pid - Process ID
27
19
  * @param tid - Thread ID
28
- * @returns Combined numeric ID
20
+ * @returns Frame tree node ID as a number
29
21
  */
30
22
  export const frameTreeNodeId = (pid, tid) => Number.parseInt(`${pid}0${tid}`, 10);
31
23
  /**
32
- * Generates a frame name string from process and thread IDs.
24
+ * Generates a frame name from process and thread IDs.
33
25
  * @param pid - Process ID
34
26
  * @param tid - Thread ID
35
- * @returns Formatted frame name
27
+ * @returns Frame name string in format FRAME0P{pid}T{tid}
36
28
  */
37
29
  export const frameName = (pid, tid) => `FRAME0P${pid}T${tid}`;
38
30
  /**
39
- * Creates an instant trace event for marking a point in time.
40
- * @param opt - Event configuration options
41
- * @returns InstantEvent object
31
+ * Core factory for creating trace events with defaults.
32
+ * @param opt - Partial trace event with required name and ph
33
+ * @returns Complete TraceEvent with defaults applied
42
34
  */
43
- export const getInstantEvent = (opt) => ({
44
- cat: 'blink.user_timing',
45
- ph: 'i',
46
- name: opt.name,
47
- ...defaults(opt),
48
- args: opt.args ?? {},
35
+ const baseEvent = (opt) => ({
36
+ cat: opt.cat ?? 'blink.user_timing',
37
+ pid: opt.pid ?? process.pid,
38
+ tid: opt.tid ?? threadId,
39
+ ts: opt.ts ?? defaultClock.epochNowUs(),
40
+ ...opt,
49
41
  });
42
+ /**
43
+ * Creates an instant trace event for marking a point in time.
44
+ * @param name - Event name
45
+ * @param ts - Optional timestamp in microseconds
46
+ * @param opt - Optional event configuration
47
+ * @returns Instant trace event (ph: 'I')
48
+ */
49
+ export const instant = (name, ts, opt) => baseEvent({ name, ph: 'I', ts, ...opt });
50
+ /**
51
+ * Creates a pair of begin and end span events.
52
+ * @param name - Span name
53
+ * @param tsB - Begin timestamp in microseconds
54
+ * @param tsE - End timestamp in microseconds
55
+ * @param opt - Optional event configuration
56
+ * @param opt.tsMarkerPadding - Padding to apply to timestamps (default: 1)
57
+ * @returns Array of [begin event, end event]
58
+ */
59
+ export const span = (name, tsB, tsE, opt) => {
60
+ const id2 = opt?.id2 ?? nextId2();
61
+ const pad = opt?.tsMarkerPadding ?? 1;
62
+ const { tsMarkerPadding, ...eventOpt } = opt ?? {};
63
+ const args = eventOpt.args ?? {};
64
+ return [
65
+ baseEvent({ name, ph: 'b', ts: tsB + pad, id2, ...eventOpt, args }),
66
+ baseEvent({ name, ph: 'e', ts: tsE - pad, id2, ...eventOpt, args }),
67
+ ];
68
+ };
50
69
  /**
51
70
  * Creates a start tracing event with frame information.
52
71
  * This event is needed at the beginning of the traceEvents array to make tell the UI profiling has started, and it should visualize the data.
@@ -54,18 +73,19 @@ export const getInstantEvent = (opt) => ({
54
73
  * @returns StartTracingEvent object
55
74
  */
56
75
  export const getInstantEventTracingStartedInBrowser = (opt) => {
57
- const { pid, tid, ts } = defaults(opt);
58
- const id = frameTreeNodeId(pid, tid);
76
+ const pid = opt.pid ?? process.pid;
77
+ const tid = opt.tid ?? threadId;
78
+ const ts = opt.ts ?? defaultClock.epochNowUs();
59
79
  return {
60
80
  cat: 'devtools.timeline',
61
- ph: 'i',
81
+ ph: 'I',
62
82
  name: 'TracingStartedInBrowser',
63
83
  pid,
64
84
  tid,
65
85
  ts,
66
86
  args: {
67
87
  data: {
68
- frameTreeNodeId: id,
88
+ frameTreeNodeId: frameTreeNodeId(pid, tid),
69
89
  frames: [
70
90
  {
71
91
  frame: frameName(pid, tid),
@@ -83,93 +103,44 @@ export const getInstantEventTracingStartedInBrowser = (opt) => {
83
103
  };
84
104
  /**
85
105
  * Creates a complete trace event with duration.
86
- * @param opt - Event configuration with name and duration
87
- * @returns CompleteEvent object
106
+ * @param name - Event name
107
+ * @param dur - Duration in microseconds
108
+ * @param opt - Optional event configuration
109
+ * @returns Complete trace event (ph: 'X')
88
110
  */
89
- export const getCompleteEvent = (opt) => ({
111
+ export const complete = (name, dur, opt) => baseEvent({
90
112
  cat: 'devtools.timeline',
91
113
  ph: 'X',
92
- name: opt.name,
93
- dur: opt.dur,
94
- ...defaults(opt),
114
+ name,
115
+ dur,
95
116
  args: {},
117
+ ...opt,
96
118
  });
97
- /**
98
- * Creates a span event (begin or end).
99
- * @param ph - Phase ('b' or 'e')
100
- * @param opt - Span event options
101
- * @returns SpanEvent object
102
- */
103
- export function getSpanEvent(ph, opt) {
104
- return {
105
- cat: 'blink.user_timing',
106
- ph,
107
- name: opt.name,
108
- id2: opt.id2,
109
- ...defaults(opt),
110
- args: opt.args?.data?.detail
111
- ? { data: { detail: opt.args.data.detail } }
112
- : {},
113
- };
114
- }
115
- /**
116
- * Creates a pair of begin and end span events.
117
- * @param opt - Span configuration with start/end timestamps
118
- * @returns Tuple of BeginEvent and EndEvent
119
- */
120
- export const getSpan = (opt) => {
121
- // tsMarkerPadding is here to make the measure slightly smaller so the markers align perfectly.
122
- // Otherwise, the marker is visible at the start of the measure below the frame
123
- // No padding Padding
124
- // spans: ======== |======|
125
- // marks: | |
126
- const pad = opt.tsMarkerPadding ?? 1;
127
- // b|e need to share the same id2
128
- const id2 = opt.id2 ?? nextId2();
129
- return [
130
- getSpanEvent('b', {
131
- ...opt,
132
- id2,
133
- ts: opt.tsB + pad,
134
- }),
135
- getSpanEvent('e', {
136
- ...opt,
137
- id2,
138
- ts: opt.tsE - pad,
139
- }),
140
- ];
141
- };
142
119
  /**
143
120
  * Converts a PerformanceMark to an instant trace event.
144
121
  * @param entry - Performance mark entry
145
122
  * @param opt - Optional overrides for name, pid, and tid
146
- * @returns InstantEvent object
123
+ * @returns Instant trace event
147
124
  */
148
- export const markToInstantEvent = (entry, opt) => getInstantEvent({
149
- ...opt,
150
- name: opt?.name ?? entry.name,
151
- ts: defaultClock.fromEntry(entry),
152
- args: entry.detail ? { detail: entry.detail } : undefined,
153
- });
125
+ export const markToInstantEvent = (entry, opt) => instant(opt?.name ?? entry.name, defaultClock.fromEntry(entry), entry.detail
126
+ ? { args: { data: { detail: entry.detail } }, ...opt }
127
+ : { args: {}, ...opt });
154
128
  /**
155
129
  * Converts a PerformanceMeasure to a pair of span events.
156
130
  * @param entry - Performance measure entry
157
131
  * @param opt - Optional overrides for name, pid, and tid
158
- * @returns Tuple of BeginEvent and EndEvent
132
+ * @returns Array of [begin event, end event]
159
133
  */
160
- export const measureToSpanEvents = (entry, opt) => getSpan({
134
+ export const measureToSpanEvents = (entry, opt) => span(opt?.name ?? entry.name, defaultClock.fromEntry(entry), defaultClock.fromEntry(entry, true), {
161
135
  ...opt,
162
- name: opt?.name ?? entry.name,
163
- tsB: defaultClock.fromEntry(entry),
164
- tsE: defaultClock.fromEntry(entry, true),
165
- args: entry.detail ? { data: { detail: entry.detail } } : undefined,
136
+ args: entry.detail ? { detail: entry.detail } : {},
166
137
  });
167
138
  /**
168
- * Converts a PerformanceEntry to an array of UserTimingTraceEvents.
139
+ * Converts a PerformanceEntry to an array of trace events.
169
140
  * A mark is converted to an instant event, and a measure is converted to a pair of span events.
170
141
  * Other entry types are ignored.
171
142
  * @param entry - Performance entry
172
- * @returns UserTimingTraceEvent[]
143
+ * @returns Array of trace events
173
144
  */
174
145
  export function entryToTraceEvents(entry) {
175
146
  if (entry.entryType === 'mark') {
@@ -180,18 +151,71 @@ export function entryToTraceEvents(entry) {
180
151
  }
181
152
  return [];
182
153
  }
154
+ /**
155
+ * Creates a mapper function for transforming detail properties in args.
156
+ * @param fn - Transformation function to apply to detail values
157
+ * @returns Function that maps args object
158
+ */
159
+ const mapArgs = (fn) => (args) => args && {
160
+ ...args,
161
+ ...(args.detail != null && { detail: fn(args.detail) }),
162
+ ...(args.data?.detail != null && {
163
+ data: { ...args.data, detail: fn(args.data.detail) },
164
+ }),
165
+ };
166
+ /**
167
+ * Encodes a trace event by converting object details to JSON strings.
168
+ * @param e - Trace event with potentially object details
169
+ * @returns Trace event with string-encoded details
170
+ */
171
+ export const encodeEvent = (e) => {
172
+ const mappedArgs = mapArgs(d => typeof d === 'object' ? JSON.stringify(d) : d)(e.args);
173
+ return {
174
+ ...e,
175
+ ...(mappedArgs && { args: mappedArgs }),
176
+ };
177
+ };
178
+ /**
179
+ * Decodes a trace event by parsing JSON string details back to objects.
180
+ * @param e - Trace event with potentially string-encoded details
181
+ * @returns Trace event with decoded object details
182
+ */
183
+ export const decodeEvent = (e) => {
184
+ const mappedArgs = mapArgs(d => (typeof d === 'string' ? JSON.parse(d) : d))(e.args);
185
+ return {
186
+ ...e,
187
+ ...(mappedArgs && { args: mappedArgs }),
188
+ };
189
+ };
190
+ /**
191
+ * Serializes a trace event to a JSON string for storage.
192
+ * First encodes the event structure (converting object details to JSON strings),
193
+ * then stringifies the entire event.
194
+ * @param event - Trace event to serialize
195
+ * @returns JSON string representation of the encoded trace event
196
+ */
197
+ export const serializeTraceEvent = (event) => JSON.stringify(encodeEvent(event));
198
+ /**
199
+ * Deserializes a JSON string back to a trace event.
200
+ * First parses the JSON string, then decodes the event structure
201
+ * (parsing JSON string details back to objects).
202
+ * @param json - JSON string representation of a trace event
203
+ * @returns Decoded trace event
204
+ */
205
+ export const deserializeTraceEvent = (json) => decodeEvent(JSON.parse(json));
183
206
  /**
184
207
  * Creates trace metadata object with standard DevTools fields and custom metadata.
185
208
  * @param startDate - Optional start date for the trace, defaults to current date
186
209
  * @param metadata - Optional additional metadata to merge into the trace metadata
187
210
  * @returns TraceMetadata object with source, startTime, and merged custom metadata
188
211
  */
189
- export function getTraceMetadata(startDate, metadata) {
212
+ export function getTraceMetadata({ startDate, ...metadata } = {}) {
213
+ const parsedStartDate = (startDate instanceof Date ? startDate : new Date()).toISOString();
190
214
  return {
191
215
  source: 'DevTools',
192
- startTime: startDate?.toISOString() ?? new Date().toISOString(),
193
- hardwareConcurrency: 1,
216
+ startTime: parsedStartDate,
194
217
  dataOrigin: 'TraceEvents',
218
+ hardwareConcurrency: os.availableParallelism(),
195
219
  ...metadata,
196
220
  };
197
221
  }
@@ -200,91 +224,9 @@ export function getTraceMetadata(startDate, metadata) {
200
224
  * @param opt - Trace file configuration
201
225
  * @returns TraceEventContainer with events and metadata
202
226
  */
203
- export const getTraceFile = (opt) => ({
204
- traceEvents: opt.traceEvents,
227
+ export const createTraceFile = (opt) => ({
228
+ traceEvents: opt.traceEvents.map(encodeEvent),
205
229
  displayTimeUnit: 'ms',
206
- metadata: getTraceMetadata(opt.startTime ? new Date(opt.startTime) : new Date(), opt.metadata),
230
+ metadata: getTraceMetadata(opt.metadata),
207
231
  });
208
- /**
209
- * Processes the detail property of an object using a custom processor function.
210
- * @template T - Object type that may contain a detail property
211
- * @param target - Object containing the detail property to process
212
- * @param processor - Function to transform the detail value
213
- * @returns New object with processed detail property, or original object if no detail
214
- */
215
- function processDetail(target, processor) {
216
- if (target.detail != null &&
217
- (typeof target.detail === 'string' || typeof target.detail === 'object')) {
218
- return { ...target, detail: processor(target.detail) };
219
- }
220
- return target;
221
- }
222
- /**
223
- * Decodes a JSON string detail property back to its original object form.
224
- * @param target - Object containing a detail property as a JSON string
225
- * @returns UserTimingDetail with the detail property parsed from JSON
226
- */
227
- export function decodeDetail(target) {
228
- return processDetail(target, detail => typeof detail === 'string'
229
- ? JSON.parse(detail)
230
- : detail);
231
- }
232
- /**
233
- * Encodes object detail properties to JSON strings for storage/transmission.
234
- * @param target - UserTimingDetail object with detail property to encode
235
- * @returns UserTimingDetail with object details converted to JSON strings
236
- */
237
- export function encodeDetail(target) {
238
- return processDetail(target, (detail) => typeof detail === 'object'
239
- ? JSON.stringify(detail)
240
- : detail);
241
- }
242
- /**
243
- * Decodes a raw trace event with JSON string details back to typed UserTimingTraceEvent.
244
- * Parses detail properties from JSON strings to objects.
245
- * @param event - Raw trace event with string-encoded details
246
- * @returns UserTimingTraceEvent with parsed detail objects
247
- */
248
- export function decodeTraceEvent({ args, ...rest }) {
249
- if (!args) {
250
- return rest;
251
- }
252
- const processedArgs = decodeDetail(args);
253
- if ('data' in args && args.data && typeof args.data === 'object') {
254
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
255
- return {
256
- ...rest,
257
- args: {
258
- ...processedArgs,
259
- data: decodeDetail(args.data),
260
- },
261
- };
262
- }
263
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
264
- return { ...rest, args: processedArgs };
265
- }
266
- /**
267
- * Encodes a UserTimingTraceEvent to raw format with JSON string details.
268
- * Converts object details to JSON strings for storage/transmission.
269
- * @param event - UserTimingTraceEvent with object details
270
- * @returns TraceEventRaw with string-encoded details
271
- */
272
- export function encodeTraceEvent({ args, ...rest }) {
273
- if (!args) {
274
- return rest;
275
- }
276
- const processedArgs = encodeDetail(args);
277
- if ('data' in args && args.data && typeof args.data === 'object') {
278
- const result = {
279
- ...rest,
280
- args: {
281
- ...processedArgs,
282
- data: encodeDetail(args.data),
283
- },
284
- };
285
- return result;
286
- }
287
- const result = { ...rest, args: processedArgs };
288
- return result;
289
- }
290
232
  //# sourceMappingURL=trace-file-utils.js.map