@code-pushup/utils 0.103.0 → 0.105.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 +3 -3
- package/src/lib/clock-epoch.d.ts +10 -0
- package/src/lib/clock-epoch.js +3 -0
- package/src/lib/clock-epoch.js.map +1 -1
- package/src/lib/performance-observer.d.ts +1 -1
- package/src/lib/sink-source.type.js +2 -0
- package/src/lib/sink-source.type.js.map +1 -0
- package/src/lib/trace-file-utils.d.ts +133 -0
- package/src/lib/trace-file-utils.js +179 -0
- package/src/lib/trace-file-utils.js.map +1 -0
- package/src/lib/trace-file.type.d.ts +279 -0
- package/src/lib/trace-file.type.js +2 -0
- package/src/lib/trace-file.type.js.map +1 -0
- package/src/lib/user-timing-extensibility-api-utils.d.ts +265 -18
- package/src/lib/user-timing-extensibility-api-utils.js +222 -7
- package/src/lib/user-timing-extensibility-api-utils.js.map +1 -1
- package/src/lib/user-timing-extensibility-api.type.d.ts +23 -2
- package/src/lib/sink-source.types.js +0 -2
- package/src/lib/sink-source.types.js.map +0 -1
- /package/src/lib/{sink-source.types.d.ts → sink-source.type.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-file.type.js","sourceRoot":"","sources":["../../../src/lib/trace-file.type.ts"],"names":[],"mappings":""}
|
|
@@ -1,11 +1,44 @@
|
|
|
1
|
-
import type { DevToolsColor, DevToolsProperties, MarkOptionsWithDevtools, MarkerPayload, MeasureOptionsWithDevtools, TrackEntryPayload } from './user-timing-extensibility-api.type.js';
|
|
2
|
-
|
|
1
|
+
import type { ActionTrackEntryPayload, DevToolsColor, DevToolsProperties, EntryMeta, MarkOptionsWithDevtools, MarkerPayload, MeasureOptionsWithDevtools, TrackEntryPayload } from './user-timing-extensibility-api.type.js';
|
|
2
|
+
/**
|
|
3
|
+
* Merges DevTools properties with override priority.
|
|
4
|
+
* @param baseProperties - Base properties array
|
|
5
|
+
* @param overrideProperties - Override properties array
|
|
6
|
+
* @returns Merged properties array
|
|
7
|
+
*/
|
|
8
|
+
export declare function mergePropertiesWithOverwrite<const T extends DevToolsProperties, const U extends DevToolsProperties>(baseProperties: T, overrideProperties: U): (T[number] | U[number])[];
|
|
9
|
+
export declare function mergePropertiesWithOverwrite<const T extends DevToolsProperties>(baseProperties: T): T;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a marker payload with default data type.
|
|
12
|
+
* @param options - Marker options excluding dataType
|
|
13
|
+
* @returns Complete marker payload
|
|
14
|
+
* @example
|
|
15
|
+
* const payload = markerPayload({
|
|
16
|
+
* color: 'primary',
|
|
17
|
+
* tooltipText: 'User action completed',
|
|
18
|
+
* properties: [['action', 'save'], ['duration', 150]]
|
|
19
|
+
* });
|
|
20
|
+
* // { dataType: 'marker', color: 'primary', tooltipText: 'User action completed', ... }
|
|
21
|
+
*/
|
|
3
22
|
export declare function markerPayload(options?: Omit<MarkerPayload, 'dataType'>): {
|
|
4
23
|
color?: DevToolsColor;
|
|
5
24
|
tooltipText?: string;
|
|
6
25
|
properties?: DevToolsProperties;
|
|
7
26
|
dataType: "marker";
|
|
8
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Creates a track entry payload with default data type.
|
|
30
|
+
* @param options - Track entry options excluding dataType
|
|
31
|
+
* @returns Complete track entry payload
|
|
32
|
+
* @example
|
|
33
|
+
* const payload = trackEntryPayload({
|
|
34
|
+
* track: 'user-interactions',
|
|
35
|
+
* trackGroup: 'frontend',
|
|
36
|
+
* color: 'secondary',
|
|
37
|
+
* tooltipText: 'Button click processed',
|
|
38
|
+
* properties: [['element', 'save-button'], ['response-time', 200]]
|
|
39
|
+
* });
|
|
40
|
+
* // { dataType: 'track-entry', track: 'user-interactions', ... }
|
|
41
|
+
*/
|
|
9
42
|
export declare function trackEntryPayload(options: Omit<TrackEntryPayload, 'dataType'>): {
|
|
10
43
|
color?: DevToolsColor | undefined;
|
|
11
44
|
tooltipText?: string | undefined;
|
|
@@ -14,59 +47,273 @@ export declare function trackEntryPayload(options: Omit<TrackEntryPayload, 'data
|
|
|
14
47
|
dataType: "track-entry";
|
|
15
48
|
track: string;
|
|
16
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* Creates an error marker payload with red color.
|
|
52
|
+
* @param options - Marker options excluding dataType and color
|
|
53
|
+
* @returns Error marker payload
|
|
54
|
+
*/
|
|
17
55
|
export declare function markerErrorPayload<T extends DevToolsColor>(options?: Omit<MarkerPayload, 'dataType' | 'color'>): {
|
|
18
56
|
tooltipText?: string;
|
|
19
57
|
properties?: DevToolsProperties;
|
|
20
58
|
dataType: "marker";
|
|
21
59
|
color: T;
|
|
22
60
|
};
|
|
23
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Creates an error track entry payload with red color.
|
|
63
|
+
* @param options - Track entry options excluding color and dataType
|
|
64
|
+
* @returns Error track entry payload
|
|
65
|
+
*/
|
|
66
|
+
export declare function trackEntryErrorPayload<T extends string>(options: Omit<TrackEntryPayload, 'color' | 'dataType'> & {
|
|
24
67
|
track: T;
|
|
25
|
-
color?: C;
|
|
26
68
|
}): {
|
|
27
69
|
tooltipText?: string | undefined;
|
|
28
70
|
properties?: DevToolsProperties | undefined;
|
|
29
71
|
trackGroup?: string | undefined;
|
|
30
72
|
dataType: "track-entry";
|
|
31
|
-
color:
|
|
73
|
+
color: "error";
|
|
32
74
|
track: T;
|
|
33
75
|
};
|
|
76
|
+
/**
|
|
77
|
+
* Converts an error to DevTools properties array.
|
|
78
|
+
* @param e - Error object or value
|
|
79
|
+
* @returns Array of error properties for DevTools
|
|
80
|
+
*/
|
|
34
81
|
export declare function errorToDevToolsProperties(e: unknown): (["Error Type", string] | ["Error Message", string])[];
|
|
82
|
+
/**
|
|
83
|
+
* Converts an error to entry metadata for DevTools.
|
|
84
|
+
* @param e - Error object or value
|
|
85
|
+
* @param options - Additional metadata options
|
|
86
|
+
* @returns Entry metadata with error properties
|
|
87
|
+
*/
|
|
35
88
|
export declare function errorToEntryMeta(e: unknown, options?: {
|
|
36
89
|
tooltipText?: string;
|
|
37
90
|
properties?: DevToolsProperties;
|
|
38
91
|
}): {
|
|
39
92
|
tooltipText?: string | undefined;
|
|
40
|
-
properties: [string, string | number | boolean | object | undefined][];
|
|
93
|
+
properties: ([key: string, value: string | number | boolean | object | undefined] | ["Error Type", string] | ["Error Message", string])[];
|
|
41
94
|
};
|
|
95
|
+
/**
|
|
96
|
+
* Converts an error to a track entry payload with error styling.
|
|
97
|
+
* @param error - Error object or value
|
|
98
|
+
* @param detail - Track entry details excluding color and dataType
|
|
99
|
+
* @returns Error track entry payload
|
|
100
|
+
*/
|
|
42
101
|
export declare function errorToTrackEntryPayload<T extends string>(error: unknown, detail: Omit<TrackEntryPayload, 'color' | 'dataType'> & {
|
|
43
102
|
track: T;
|
|
44
103
|
}): {
|
|
45
104
|
tooltipText?: string | undefined;
|
|
46
|
-
properties: [string, string | number | boolean | object | undefined][];
|
|
105
|
+
properties: ([key: string, value: string | number | boolean | object | undefined] | ["Error Type", string] | ["Error Message", string])[];
|
|
47
106
|
track: T;
|
|
48
107
|
trackGroup?: string | undefined;
|
|
49
108
|
dataType: "track-entry";
|
|
50
109
|
color: "error";
|
|
51
110
|
};
|
|
111
|
+
/**
|
|
112
|
+
* Converts an error to a marker payload with error styling.
|
|
113
|
+
* @param error - Error object or value
|
|
114
|
+
* @param detail - Marker details excluding color and dataType
|
|
115
|
+
* @returns Error marker payload
|
|
116
|
+
*/
|
|
52
117
|
export declare function errorToMarkerPayload(error: unknown, detail?: Omit<MarkerPayload, 'color' | 'dataType'>): {
|
|
53
118
|
tooltipText?: string | undefined;
|
|
54
|
-
properties: [string, string | number | boolean | object | undefined][];
|
|
119
|
+
properties: ([key: string, value: string | number | boolean | object | undefined] | ["Error Type", string] | ["Error Message", string])[];
|
|
55
120
|
dataType: "marker";
|
|
56
121
|
color: "error";
|
|
57
122
|
};
|
|
58
123
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
124
|
+
* Converts DevTools payload to performance API options format.
|
|
125
|
+
* @param devtools - DevTools payload or null
|
|
126
|
+
* @returns Performance API options with DevTools detail
|
|
61
127
|
* @example
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
128
|
+
* const marker = markerPayload({ color: 'primary', tooltipText: 'Start' });
|
|
129
|
+
* performance.mark('start', asOptions(marker));
|
|
130
|
+
*
|
|
131
|
+
* const trackEntry = trackEntryPayload({ track: 'operations', color: 'tertiary' });
|
|
132
|
+
* performance.measure('operation', {
|
|
133
|
+
* start: 'start',
|
|
134
|
+
* end: 'end',
|
|
135
|
+
* ...asOptions(trackEntry)
|
|
136
|
+
* });
|
|
70
137
|
*/
|
|
71
138
|
export declare function asOptions<T extends MarkerPayload>(devtools?: T | null): MarkOptionsWithDevtools<T>;
|
|
72
139
|
export declare function asOptions<T extends TrackEntryPayload>(devtools?: T | null): MeasureOptionsWithDevtools<T>;
|
|
140
|
+
/**
|
|
141
|
+
* Generates start, end, and measure names for performance tracking.
|
|
142
|
+
* @param base - Base name for the measurement
|
|
143
|
+
* @returns Object with startName, endName, and measureName
|
|
144
|
+
*/
|
|
145
|
+
export type Names<N extends string> = {
|
|
146
|
+
startName: `${N}:start`;
|
|
147
|
+
endName: `${N}:end`;
|
|
148
|
+
measureName: N;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Generates start, end, and measure names for performance tracking.
|
|
152
|
+
* @param base - Base name for the measurement
|
|
153
|
+
* @param prefix - Optional prefix for names
|
|
154
|
+
* @returns Object with startName, endName, and measureName
|
|
155
|
+
*/
|
|
156
|
+
export declare function getNames<T extends string>(base: T): Names<T>;
|
|
157
|
+
export declare function getNames<T extends string, P extends string>(base: T, prefix?: P): Names<`${P}:${T}`>;
|
|
158
|
+
/**
|
|
159
|
+
* Removes undefined from a type, effectively filtering out undefined values.
|
|
160
|
+
*/
|
|
161
|
+
type Defined<T> = T extends undefined ? never : T;
|
|
162
|
+
/**
|
|
163
|
+
* Merges two objects with the specified overwrite semantics:
|
|
164
|
+
* - If B[K] is undefined → keep A[K]
|
|
165
|
+
* - If B[K] is defined → overwrite with Defined<B[K]>
|
|
166
|
+
* - Keys only in A → keep A[K]
|
|
167
|
+
* - Keys only in B → take Defined<B[K]>
|
|
168
|
+
*/
|
|
169
|
+
type MergeDefined<A, B> = {
|
|
170
|
+
[K in keyof A | keyof B]: K extends keyof B ? Defined<B[K]> extends never ? K extends keyof A ? A[K] : never : Defined<B[K]> : K extends keyof A ? A[K] : never;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Recursively merges an array of objects using MergeDefined semantics.
|
|
174
|
+
* The first element is the base type, subsequent elements only overwrite with defined values.
|
|
175
|
+
*/
|
|
176
|
+
type MergeResult<P extends readonly unknown[]> = P extends readonly [
|
|
177
|
+
infer A,
|
|
178
|
+
...infer R
|
|
179
|
+
] ? MergeDefined<A & {}, MergeResult<R>> : object;
|
|
180
|
+
/**
|
|
181
|
+
* Merges multiple DevTools payloads into a single payload.
|
|
182
|
+
* The first payload establishes the base type, subsequent payloads only overwrite with defined values.
|
|
183
|
+
* @param parts - Array of payloads where first is complete and rest are partial
|
|
184
|
+
* @returns Merged payload with combined properties
|
|
185
|
+
* @example
|
|
186
|
+
* const payload = mergeDevtoolsPayload(
|
|
187
|
+
* trackEntryPayload({ track: 'user-interactions', color: 'secondary' }),
|
|
188
|
+
* { color: 'primary', tooltipText: 'User action completed' },
|
|
189
|
+
* );
|
|
190
|
+
* // { track: 'user-interactions', color: 'primary', tooltipText: 'User action completed' }
|
|
191
|
+
*/
|
|
192
|
+
export declare function mergeDevtoolsPayload<const P extends readonly [
|
|
193
|
+
TrackEntryPayload | MarkerPayload,
|
|
194
|
+
...Partial<TrackEntryPayload | MarkerPayload>[]
|
|
195
|
+
]>(...parts: P): MergeResult<P> & {
|
|
196
|
+
properties?: DevToolsProperties;
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
* Sets up tracks with default values merged into each track.
|
|
200
|
+
* This helps to avoid repetition when defining multiple tracks with common properties.
|
|
201
|
+
* @param defaults - Default action track configuration
|
|
202
|
+
* @param tracks - Track configurations to merge with defaults
|
|
203
|
+
* @returns Record with merged track configurations
|
|
204
|
+
*/
|
|
205
|
+
export declare function setupTracks<const T extends Record<string, Partial<ActionTrackEntryPayload>>, const D extends ActionTrackEntryPayload>(defaults: D, tracks: T): Record<keyof T, MergeDefined<D & {}, MergeDefined<T[keyof T] & {}, object>> & {
|
|
206
|
+
properties?: DevToolsProperties;
|
|
207
|
+
}>;
|
|
208
|
+
/**
|
|
209
|
+
* Options for customizing measurement behavior and callbacks.
|
|
210
|
+
* Extends partial ActionTrackEntryPayload to allow overriding default track properties.
|
|
211
|
+
*/
|
|
212
|
+
export type MeasureOptions = Partial<ActionTrackEntryPayload> & {
|
|
213
|
+
/**
|
|
214
|
+
* Callback invoked when measurement completes successfully.
|
|
215
|
+
* @param result - The successful result value
|
|
216
|
+
* @returns Additional DevTools properties to merge for success state
|
|
217
|
+
*/
|
|
218
|
+
success?: (result: unknown) => Partial<ActionTrackEntryPayload>;
|
|
219
|
+
/**
|
|
220
|
+
* Callback invoked when measurement fails with an error.
|
|
221
|
+
* @param error - The error that occurred
|
|
222
|
+
* @returns Additional DevTools properties to merge for error state
|
|
223
|
+
*/
|
|
224
|
+
error?: (error: unknown) => Partial<ActionTrackEntryPayload>;
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* Configuration for creating a measurement context.
|
|
228
|
+
* Defines default behavior and appearance for all measurements in this context.
|
|
229
|
+
*/
|
|
230
|
+
export type MeasureCtxOptions = ActionTrackEntryPayload & {
|
|
231
|
+
/**
|
|
232
|
+
* Optional prefix for all measurement names to avoid conflicts.
|
|
233
|
+
* @example "api:" results in names like "api:request:start"
|
|
234
|
+
*/
|
|
235
|
+
prefix?: string;
|
|
236
|
+
} & {
|
|
237
|
+
/**
|
|
238
|
+
* Global error handler for all measurements in this context.
|
|
239
|
+
* Applied to all error states in addition to per-measurement error callbacks.
|
|
240
|
+
* @param error - The error that occurred
|
|
241
|
+
* @returns Additional DevTools metadata for error display
|
|
242
|
+
*/
|
|
243
|
+
error?: (error: unknown) => EntryMeta;
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* Creates a measurement context for tracking performance events with consistent DevTools visualization.
|
|
247
|
+
*
|
|
248
|
+
* This function returns a higher-order function that generates measurement controllers for individual events.
|
|
249
|
+
* Each measurement creates start/end marks and a final measure in Chrome DevTools Performance panel.
|
|
250
|
+
*
|
|
251
|
+
* @param cfg - Configuration defining default track properties, optional prefix, and global error handling
|
|
252
|
+
* @returns Function that creates measurement controllers for specific events
|
|
253
|
+
* @example
|
|
254
|
+
* // Basic usage with defaults
|
|
255
|
+
* const measure = measureCtx({
|
|
256
|
+
* track: 'api-calls',
|
|
257
|
+
* color: 'secondary',
|
|
258
|
+
* trackGroup: 'backend'
|
|
259
|
+
* });
|
|
260
|
+
*
|
|
261
|
+
* const { start, success, error } = measure('fetch-user');
|
|
262
|
+
* start(); // Creates "fetch-user:start" mark
|
|
263
|
+
* // ... async operation ...
|
|
264
|
+
* success({ userCount: 42 }); // Creates "fetch-user:end" mark and "fetch-user" measure
|
|
265
|
+
* @example
|
|
266
|
+
* // Advanced usage with callbacks and error handling
|
|
267
|
+
* const measure = measureCtx({
|
|
268
|
+
* track: 'user-actions',
|
|
269
|
+
* color: 'primary',
|
|
270
|
+
* error: (err) => ({
|
|
271
|
+
* properties: [['error-type', err.name], ['error-message', err.message]]
|
|
272
|
+
* })
|
|
273
|
+
* });
|
|
274
|
+
*
|
|
275
|
+
* const { start, success, error } = measure('save-form', {
|
|
276
|
+
* success: (result) => ({
|
|
277
|
+
* properties: [['items-saved', result.count]],
|
|
278
|
+
* tooltipText: `Saved ${result.count} items successfully`
|
|
279
|
+
* }),
|
|
280
|
+
* error: (err) => ({
|
|
281
|
+
* properties: [['validation-errors', err.errors?.length ?? 0]]
|
|
282
|
+
* })
|
|
283
|
+
* });
|
|
284
|
+
*
|
|
285
|
+
* start();
|
|
286
|
+
* try {
|
|
287
|
+
* const result = await saveFormData(formData);
|
|
288
|
+
* success(result);
|
|
289
|
+
* } catch (err) {
|
|
290
|
+
* error(err); // Applies both global and specific error metadata
|
|
291
|
+
* }
|
|
292
|
+
* @example
|
|
293
|
+
* // onetime config of defaults
|
|
294
|
+
* const apiMeasure = measureCtx({
|
|
295
|
+
* prefix: 'http:',
|
|
296
|
+
* track: 'api',
|
|
297
|
+
* });
|
|
298
|
+
*
|
|
299
|
+
* const { start, success, error } = apiMeasure('login');
|
|
300
|
+
*
|
|
301
|
+
* start();
|
|
302
|
+
* try {
|
|
303
|
+
* const result = myWork();
|
|
304
|
+
* success(result);
|
|
305
|
+
* return result;
|
|
306
|
+
* } catch(err) {
|
|
307
|
+
* error(err)
|
|
308
|
+
* }
|
|
309
|
+
* @returns Object with measurement control methods:
|
|
310
|
+
* - `start()`: Marks the beginning of the measurement
|
|
311
|
+
* - `success(result?)`: Completes successful measurement with optional result metadata
|
|
312
|
+
* - `error(error)`: Completes failed measurement with error metadata
|
|
313
|
+
*/
|
|
314
|
+
export declare function measureCtx(cfg: MeasureCtxOptions): (event: string, opt?: MeasureOptions) => {
|
|
315
|
+
start: () => import("perf_hooks").PerformanceMark;
|
|
316
|
+
success: (r: unknown) => void;
|
|
317
|
+
error: (err: unknown) => void;
|
|
318
|
+
};
|
|
319
|
+
export {};
|
|
@@ -1,16 +1,42 @@
|
|
|
1
|
+
import { performance } from 'node:perf_hooks';
|
|
2
|
+
import { objectFromEntries, objectToEntries } from './transform.js';
|
|
1
3
|
const dataTypeTrackEntry = 'track-entry';
|
|
2
4
|
const dataTypeMarker = 'marker';
|
|
3
5
|
export function mergePropertiesWithOverwrite(baseProperties, overrideProperties) {
|
|
4
|
-
return [
|
|
5
|
-
...new Map([...(baseProperties ?? []), ...(overrideProperties ?? [])]),
|
|
6
|
-
];
|
|
6
|
+
return [...new Map([...baseProperties, ...(overrideProperties ?? [])])];
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates a marker payload with default data type.
|
|
10
|
+
* @param options - Marker options excluding dataType
|
|
11
|
+
* @returns Complete marker payload
|
|
12
|
+
* @example
|
|
13
|
+
* const payload = markerPayload({
|
|
14
|
+
* color: 'primary',
|
|
15
|
+
* tooltipText: 'User action completed',
|
|
16
|
+
* properties: [['action', 'save'], ['duration', 150]]
|
|
17
|
+
* });
|
|
18
|
+
* // { dataType: 'marker', color: 'primary', tooltipText: 'User action completed', ... }
|
|
19
|
+
*/
|
|
8
20
|
export function markerPayload(options) {
|
|
9
21
|
return {
|
|
10
22
|
dataType: dataTypeMarker,
|
|
11
23
|
...options,
|
|
12
24
|
};
|
|
13
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Creates a track entry payload with default data type.
|
|
28
|
+
* @param options - Track entry options excluding dataType
|
|
29
|
+
* @returns Complete track entry payload
|
|
30
|
+
* @example
|
|
31
|
+
* const payload = trackEntryPayload({
|
|
32
|
+
* track: 'user-interactions',
|
|
33
|
+
* trackGroup: 'frontend',
|
|
34
|
+
* color: 'secondary',
|
|
35
|
+
* tooltipText: 'Button click processed',
|
|
36
|
+
* properties: [['element', 'save-button'], ['response-time', 200]]
|
|
37
|
+
* });
|
|
38
|
+
* // { dataType: 'track-entry', track: 'user-interactions', ... }
|
|
39
|
+
*/
|
|
14
40
|
export function trackEntryPayload(options) {
|
|
15
41
|
const { track, ...rest } = options;
|
|
16
42
|
return {
|
|
@@ -19,6 +45,11 @@ export function trackEntryPayload(options) {
|
|
|
19
45
|
...rest,
|
|
20
46
|
};
|
|
21
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Creates an error marker payload with red color.
|
|
50
|
+
* @param options - Marker options excluding dataType and color
|
|
51
|
+
* @returns Error marker payload
|
|
52
|
+
*/
|
|
22
53
|
export function markerErrorPayload(options) {
|
|
23
54
|
return {
|
|
24
55
|
dataType: dataTypeMarker,
|
|
@@ -26,15 +57,25 @@ export function markerErrorPayload(options) {
|
|
|
26
57
|
...options,
|
|
27
58
|
};
|
|
28
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Creates an error track entry payload with red color.
|
|
62
|
+
* @param options - Track entry options excluding color and dataType
|
|
63
|
+
* @returns Error track entry payload
|
|
64
|
+
*/
|
|
29
65
|
export function trackEntryErrorPayload(options) {
|
|
30
|
-
const { track,
|
|
66
|
+
const { track, ...restOptions } = options;
|
|
31
67
|
return {
|
|
32
68
|
dataType: dataTypeTrackEntry,
|
|
33
|
-
color,
|
|
69
|
+
color: 'error',
|
|
34
70
|
track,
|
|
35
71
|
...restOptions,
|
|
36
72
|
};
|
|
37
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Converts an error to DevTools properties array.
|
|
76
|
+
* @param e - Error object or value
|
|
77
|
+
* @returns Array of error properties for DevTools
|
|
78
|
+
*/
|
|
38
79
|
export function errorToDevToolsProperties(e) {
|
|
39
80
|
const name = e instanceof Error ? e.name : 'UnknownError';
|
|
40
81
|
const message = e instanceof Error ? e.message : String(e);
|
|
@@ -43,14 +84,26 @@ export function errorToDevToolsProperties(e) {
|
|
|
43
84
|
['Error Message', message],
|
|
44
85
|
];
|
|
45
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Converts an error to entry metadata for DevTools.
|
|
89
|
+
* @param e - Error object or value
|
|
90
|
+
* @param options - Additional metadata options
|
|
91
|
+
* @returns Entry metadata with error properties
|
|
92
|
+
*/
|
|
46
93
|
export function errorToEntryMeta(e, options) {
|
|
47
94
|
const { properties, tooltipText } = options ?? {};
|
|
48
|
-
const props = mergePropertiesWithOverwrite(errorToDevToolsProperties(e), properties);
|
|
95
|
+
const props = mergePropertiesWithOverwrite(errorToDevToolsProperties(e), properties ?? []);
|
|
49
96
|
return {
|
|
50
97
|
properties: props,
|
|
51
98
|
...(tooltipText ? { tooltipText } : {}),
|
|
52
99
|
};
|
|
53
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Converts an error to a track entry payload with error styling.
|
|
103
|
+
* @param error - Error object or value
|
|
104
|
+
* @param detail - Track entry details excluding color and dataType
|
|
105
|
+
* @returns Error track entry payload
|
|
106
|
+
*/
|
|
54
107
|
export function errorToTrackEntryPayload(error, detail) {
|
|
55
108
|
const { properties, tooltipText, ...trackPayload } = detail;
|
|
56
109
|
return {
|
|
@@ -63,6 +116,12 @@ export function errorToTrackEntryPayload(error, detail) {
|
|
|
63
116
|
}),
|
|
64
117
|
};
|
|
65
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Converts an error to a marker payload with error styling.
|
|
121
|
+
* @param error - Error object or value
|
|
122
|
+
* @param detail - Marker details excluding color and dataType
|
|
123
|
+
* @returns Error marker payload
|
|
124
|
+
*/
|
|
66
125
|
export function errorToMarkerPayload(error, detail) {
|
|
67
126
|
const { properties, tooltipText } = detail ?? {};
|
|
68
127
|
return {
|
|
@@ -75,6 +134,162 @@ export function errorToMarkerPayload(error, detail) {
|
|
|
75
134
|
};
|
|
76
135
|
}
|
|
77
136
|
export function asOptions(devtools) {
|
|
78
|
-
|
|
137
|
+
if (devtools == null) {
|
|
138
|
+
return { detail: {} };
|
|
139
|
+
}
|
|
140
|
+
return { detail: { devtools } };
|
|
141
|
+
}
|
|
142
|
+
export function getNames(base, prefix) {
|
|
143
|
+
const n = prefix ? `${prefix}:${base}` : base;
|
|
144
|
+
return {
|
|
145
|
+
startName: `${n}:start`,
|
|
146
|
+
endName: `${n}:end`,
|
|
147
|
+
measureName: n,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Merges multiple DevTools payloads into a single payload.
|
|
152
|
+
* The first payload establishes the base type, subsequent payloads only overwrite with defined values.
|
|
153
|
+
* @param parts - Array of payloads where first is complete and rest are partial
|
|
154
|
+
* @returns Merged payload with combined properties
|
|
155
|
+
* @example
|
|
156
|
+
* const payload = mergeDevtoolsPayload(
|
|
157
|
+
* trackEntryPayload({ track: 'user-interactions', color: 'secondary' }),
|
|
158
|
+
* { color: 'primary', tooltipText: 'User action completed' },
|
|
159
|
+
* );
|
|
160
|
+
* // { track: 'user-interactions', color: 'primary', tooltipText: 'User action completed' }
|
|
161
|
+
*/
|
|
162
|
+
export function mergeDevtoolsPayload(...parts) {
|
|
163
|
+
return parts.reduce((acc, cur) => ({
|
|
164
|
+
...acc,
|
|
165
|
+
...cur,
|
|
166
|
+
...(cur.properties || acc.properties
|
|
167
|
+
? {
|
|
168
|
+
properties: mergePropertiesWithOverwrite(acc.properties ?? [], cur.properties ?? []),
|
|
169
|
+
}
|
|
170
|
+
: {}),
|
|
171
|
+
}),
|
|
172
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
173
|
+
{});
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Sets up tracks with default values merged into each track.
|
|
177
|
+
* This helps to avoid repetition when defining multiple tracks with common properties.
|
|
178
|
+
* @param defaults - Default action track configuration
|
|
179
|
+
* @param tracks - Track configurations to merge with defaults
|
|
180
|
+
* @returns Record with merged track configurations
|
|
181
|
+
*/
|
|
182
|
+
export function setupTracks(defaults, tracks) {
|
|
183
|
+
return objectFromEntries(objectToEntries(tracks).map(([key, track]) => [
|
|
184
|
+
key,
|
|
185
|
+
mergeDevtoolsPayload(defaults, track),
|
|
186
|
+
]));
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* This is a helper function used to ensure that the marks used to create a measure do not contain UI interaction properties.
|
|
190
|
+
* @param devtools - The devtools payload to convert to mark options.
|
|
191
|
+
* @returns The mark options without dataType, tooltipText and properties.
|
|
192
|
+
*/
|
|
193
|
+
function toMarkMeasureOpts(devtools) {
|
|
194
|
+
const { dataType: _, tooltipText: __, properties: ___, ...markDevtools } = devtools;
|
|
195
|
+
return { detail: { devtools: markDevtools } };
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Creates a measurement context for tracking performance events with consistent DevTools visualization.
|
|
199
|
+
*
|
|
200
|
+
* This function returns a higher-order function that generates measurement controllers for individual events.
|
|
201
|
+
* Each measurement creates start/end marks and a final measure in Chrome DevTools Performance panel.
|
|
202
|
+
*
|
|
203
|
+
* @param cfg - Configuration defining default track properties, optional prefix, and global error handling
|
|
204
|
+
* @returns Function that creates measurement controllers for specific events
|
|
205
|
+
* @example
|
|
206
|
+
* // Basic usage with defaults
|
|
207
|
+
* const measure = measureCtx({
|
|
208
|
+
* track: 'api-calls',
|
|
209
|
+
* color: 'secondary',
|
|
210
|
+
* trackGroup: 'backend'
|
|
211
|
+
* });
|
|
212
|
+
*
|
|
213
|
+
* const { start, success, error } = measure('fetch-user');
|
|
214
|
+
* start(); // Creates "fetch-user:start" mark
|
|
215
|
+
* // ... async operation ...
|
|
216
|
+
* success({ userCount: 42 }); // Creates "fetch-user:end" mark and "fetch-user" measure
|
|
217
|
+
* @example
|
|
218
|
+
* // Advanced usage with callbacks and error handling
|
|
219
|
+
* const measure = measureCtx({
|
|
220
|
+
* track: 'user-actions',
|
|
221
|
+
* color: 'primary',
|
|
222
|
+
* error: (err) => ({
|
|
223
|
+
* properties: [['error-type', err.name], ['error-message', err.message]]
|
|
224
|
+
* })
|
|
225
|
+
* });
|
|
226
|
+
*
|
|
227
|
+
* const { start, success, error } = measure('save-form', {
|
|
228
|
+
* success: (result) => ({
|
|
229
|
+
* properties: [['items-saved', result.count]],
|
|
230
|
+
* tooltipText: `Saved ${result.count} items successfully`
|
|
231
|
+
* }),
|
|
232
|
+
* error: (err) => ({
|
|
233
|
+
* properties: [['validation-errors', err.errors?.length ?? 0]]
|
|
234
|
+
* })
|
|
235
|
+
* });
|
|
236
|
+
*
|
|
237
|
+
* start();
|
|
238
|
+
* try {
|
|
239
|
+
* const result = await saveFormData(formData);
|
|
240
|
+
* success(result);
|
|
241
|
+
* } catch (err) {
|
|
242
|
+
* error(err); // Applies both global and specific error metadata
|
|
243
|
+
* }
|
|
244
|
+
* @example
|
|
245
|
+
* // onetime config of defaults
|
|
246
|
+
* const apiMeasure = measureCtx({
|
|
247
|
+
* prefix: 'http:',
|
|
248
|
+
* track: 'api',
|
|
249
|
+
* });
|
|
250
|
+
*
|
|
251
|
+
* const { start, success, error } = apiMeasure('login');
|
|
252
|
+
*
|
|
253
|
+
* start();
|
|
254
|
+
* try {
|
|
255
|
+
* const result = myWork();
|
|
256
|
+
* success(result);
|
|
257
|
+
* return result;
|
|
258
|
+
* } catch(err) {
|
|
259
|
+
* error(err)
|
|
260
|
+
* }
|
|
261
|
+
* @returns Object with measurement control methods:
|
|
262
|
+
* - `start()`: Marks the beginning of the measurement
|
|
263
|
+
* - `success(result?)`: Completes successful measurement with optional result metadata
|
|
264
|
+
* - `error(error)`: Completes failed measurement with error metadata
|
|
265
|
+
*/
|
|
266
|
+
export function measureCtx(cfg) {
|
|
267
|
+
const { prefix, error: globalErr, ...defaults } = cfg;
|
|
268
|
+
return (event, opt) => {
|
|
269
|
+
const { success, error, ...measurePayload } = opt ?? {};
|
|
270
|
+
const merged = mergeDevtoolsPayload(defaults, measurePayload);
|
|
271
|
+
const { startName: s, endName: e, measureName: m, } = getNames(event, prefix);
|
|
272
|
+
return {
|
|
273
|
+
start: () => performance.mark(s, toMarkMeasureOpts(merged)),
|
|
274
|
+
success: (r) => {
|
|
275
|
+
const successPayload = mergeDevtoolsPayload(merged, success?.(r) ?? {});
|
|
276
|
+
performance.mark(e, toMarkMeasureOpts(successPayload));
|
|
277
|
+
performance.measure(m, {
|
|
278
|
+
start: s,
|
|
279
|
+
end: e,
|
|
280
|
+
...asOptions(successPayload),
|
|
281
|
+
});
|
|
282
|
+
},
|
|
283
|
+
error: (err) => {
|
|
284
|
+
const errorPayload = mergeDevtoolsPayload({ ...merged, color: 'error' }, errorToEntryMeta(err), globalErr?.(err) ?? {}, error?.(err) ?? {});
|
|
285
|
+
performance.mark(e, toMarkMeasureOpts(errorPayload));
|
|
286
|
+
performance.measure(m, {
|
|
287
|
+
start: s,
|
|
288
|
+
end: e,
|
|
289
|
+
...asOptions(errorPayload),
|
|
290
|
+
});
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
};
|
|
79
294
|
}
|
|
80
295
|
//# sourceMappingURL=user-timing-extensibility-api-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-timing-extensibility-api-utils.js","sourceRoot":"","sources":["../../../src/lib/user-timing-extensibility-api-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"user-timing-extensibility-api-utils.js","sourceRoot":"","sources":["../../../src/lib/user-timing-extensibility-api-utils.ts"],"names":[],"mappings":"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"}
|