@code-pushup/utils 0.113.0 → 0.114.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/index.d.ts +2 -1
- package/src/index.js +2 -1
- package/src/index.js.map +1 -1
- package/src/lib/file-system.d.ts +0 -2
- package/src/lib/file-system.js +0 -16
- package/src/lib/file-system.js.map +1 -1
- package/src/lib/import-module.d.ts +2 -0
- package/src/lib/import-module.js +21 -0
- package/src/lib/import-module.js.map +1 -0
- package/src/lib/process-id.d.ts +83 -0
- package/src/lib/process-id.js +93 -0
- package/src/lib/process-id.js.map +1 -0
- package/src/lib/profiler/constants.d.ts +5 -0
- package/src/lib/profiler/constants.js +5 -0
- package/src/lib/profiler/constants.js.map +1 -1
- package/src/lib/profiler/profiler-node.js +11 -3
- package/src/lib/profiler/profiler-node.js.map +1 -1
- package/src/lib/profiler/trace-file-utils.d.ts +65 -116
- package/src/lib/profiler/trace-file-utils.js +127 -185
- package/src/lib/profiler/trace-file-utils.js.map +1 -1
- package/src/lib/profiler/trace-file.type.d.ts +24 -157
- package/src/lib/profiler/wal-json-trace.d.ts +11 -10
- package/src/lib/profiler/wal-json-trace.js +36 -53
- package/src/lib/profiler/wal-json-trace.js.map +1 -1
- package/src/lib/wal.d.ts +0 -28
- package/src/lib/wal.js +12 -52
- package/src/lib/wal.js.map +1 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { PerformanceEntry, PerformanceMark, PerformanceMeasure } from 'node:perf_hooks';
|
|
2
|
-
import type {
|
|
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
|
|
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
|
|
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
|
|
18
|
+
* Generates a frame name from process and thread IDs.
|
|
20
19
|
* @param pid - Process ID
|
|
21
20
|
* @param tid - Thread ID
|
|
22
|
-
* @returns
|
|
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
|
|
28
|
-
* @
|
|
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
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
|
52
|
-
* @
|
|
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
|
|
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
|
|
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
|
-
}) =>
|
|
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
|
|
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
|
-
}) => [
|
|
80
|
+
}) => TraceEvent[];
|
|
125
81
|
/**
|
|
126
|
-
* Converts a PerformanceEntry to an array of
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
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
|
|
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
|
|
24
|
+
* Generates a frame name from process and thread IDs.
|
|
33
25
|
* @param pid - Process ID
|
|
34
26
|
* @param tid - Thread ID
|
|
35
|
-
* @returns
|
|
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
|
-
*
|
|
40
|
-
* @param opt -
|
|
41
|
-
* @returns
|
|
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
|
-
|
|
44
|
-
cat: 'blink.user_timing',
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
58
|
-
const
|
|
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: '
|
|
81
|
+
ph: 'I',
|
|
62
82
|
name: 'TracingStartedInBrowser',
|
|
63
83
|
pid,
|
|
64
84
|
tid,
|
|
65
85
|
ts,
|
|
66
86
|
args: {
|
|
67
87
|
data: {
|
|
68
|
-
frameTreeNodeId:
|
|
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
|
|
87
|
-
* @
|
|
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
|
|
111
|
+
export const complete = (name, dur, opt) => baseEvent({
|
|
90
112
|
cat: 'devtools.timeline',
|
|
91
113
|
ph: 'X',
|
|
92
|
-
name
|
|
93
|
-
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
|
|
123
|
+
* @returns Instant trace event
|
|
147
124
|
*/
|
|
148
|
-
export const markToInstantEvent = (entry, opt) =>
|
|
149
|
-
...opt
|
|
150
|
-
|
|
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
|
|
132
|
+
* @returns Array of [begin event, end event]
|
|
159
133
|
*/
|
|
160
|
-
export const measureToSpanEvents = (entry, opt) =>
|
|
134
|
+
export const measureToSpanEvents = (entry, opt) => span(opt?.name ?? entry.name, defaultClock.fromEntry(entry), defaultClock.fromEntry(entry, true), {
|
|
161
135
|
...opt,
|
|
162
|
-
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
204
|
-
traceEvents: opt.traceEvents,
|
|
227
|
+
export const createTraceFile = (opt) => ({
|
|
228
|
+
traceEvents: opt.traceEvents.map(encodeEvent),
|
|
205
229
|
displayTimeUnit: 'ms',
|
|
206
|
-
metadata: getTraceMetadata(opt.
|
|
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
|