@code-pushup/utils 0.103.0 → 0.104.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-pushup/utils",
3
- "version": "0.103.0",
3
+ "version": "0.104.0",
4
4
  "description": "Low-level utilities (helper functions, etc.) used by Code PushUp CLI",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/code-pushup/cli/tree/main/packages/utils#readme",
@@ -27,7 +27,7 @@
27
27
  "node": ">=17.0.0"
28
28
  },
29
29
  "dependencies": {
30
- "@code-pushup/models": "0.103.0",
30
+ "@code-pushup/models": "0.104.0",
31
31
  "ansis": "^3.3.0",
32
32
  "build-md": "^0.4.2",
33
33
  "bundle-require": "^5.1.0",
@@ -1,5 +1,5 @@
1
1
  import { type PerformanceEntry } from 'node:perf_hooks';
2
- import type { Buffered, Encoder, Observer, Sink } from './sink-source.types.js';
2
+ import type { Buffered, Encoder, Observer, Sink } from './sink-source.type';
3
3
  export declare const DEFAULT_FLUSH_THRESHOLD = 20;
4
4
  export type PerformanceObserverOptions<T> = {
5
5
  sink: Sink<T, unknown>;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sink-source.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink-source.type.js","sourceRoot":"","sources":["../../../src/lib/sink-source.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
- export declare function mergePropertiesWithOverwrite(baseProperties: DevToolsProperties | undefined, overrideProperties?: DevToolsProperties | undefined): [string, string | number | boolean | object | undefined][];
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
- export declare function trackEntryErrorPayload<T extends string, C extends DevToolsColor>(options: Omit<TrackEntryPayload, 'color' | 'dataType'> & {
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: DevToolsColor;
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
- * asOptions wraps a DevTools payload into the `detail` property of User Timing entry options.
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
- * profiler.mark('mark', asOptions({
63
- * dataType: 'marker',
64
- * color: 'error',
65
- * tooltipText: 'This is a marker',
66
- * properties: [
67
- * ['str', 'This is a detail property']
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, color = 'error', ...restOptions } = options;
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
- return devtools == null ? { detail: {} } : { detail: { devtools } };
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":"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"}
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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"}
@@ -44,7 +44,7 @@ export type EntryMeta = {
44
44
  properties?: DevToolsProperties;
45
45
  };
46
46
  /**
47
- * Styling options for track entries in DevTools.
47
+ * Styling options for track entries and marker in DevTools.
48
48
  * @property {DevToolsColor} [color] - rendered color of background and border, defaults to "primary"
49
49
  */
50
50
  export type TrackStyle = {
@@ -53,7 +53,7 @@ export type TrackStyle = {
53
53
  /**
54
54
  * Metadata for organizing track entries in DevTools.
55
55
  * @property {string} track - Name of the custom track
56
- * @property {string} [trackGroup] - Group for organizing tracks
56
+ * @property {string} [trackGroup] - Group for organizing tracks.
57
57
  */
58
58
  export type TrackMeta = {
59
59
  track: string;
@@ -88,6 +88,21 @@ export type WithErrorColor<T extends {
88
88
  }> = Omit<T, 'color'> & {
89
89
  color: 'error';
90
90
  };
91
+ /**
92
+ * Action color payload.
93
+ * @param color - The color of the action
94
+ * @returns The action color payload
95
+ */
96
+ export type ActionColorPayload = {
97
+ color?: DevToolsActionColor;
98
+ };
99
+ /**
100
+ * Action track payload.
101
+ * @param TrackEntryPayload - The track entry payload
102
+ * @param ActionColorPayload - The action color payload
103
+ * @returns The action track payload
104
+ */
105
+ export type ActionTrackEntryPayload = TrackEntryPayload & ActionColorPayload;
91
106
  /**
92
107
  * Utility type that adds an optional devtools payload property.
93
108
  */
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=sink-source.types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sink-source.types.js","sourceRoot":"","sources":["../../../src/lib/sink-source.types.ts"],"names":[],"mappings":""}