Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"type": "module",
"engines": {
"node": ">=17.0.0"
"node": ">=18.2.0"
Comment thread
BioPhoton marked this conversation as resolved.
Outdated
},
"dependencies": {
"@code-pushup/models": "0.101.1",
Expand Down
166 changes: 166 additions & 0 deletions packages/utils/src/lib/user-timing-extensibility-api-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import type {
DevToolsColor,
DevToolsProperties,
EntryMeta,
MarkOptionsWithDevtools,
MarkerPayload,
MeasureOptionsWithDevtools,
TrackEntryPayload,
} from './user-timing-extensibility-api.type.js';

const dataTypeTrackEntry = 'track-entry';
const dataTypeMarker = 'marker';

export function objToPropertiesPayload(
object: Record<string, string | number | boolean | object | undefined>,
): DevToolsProperties {
return Object.entries(object);
Comment thread
BioPhoton marked this conversation as resolved.
Outdated
}

export function mergePropertiesWithOverwrite(
baseProperties: DevToolsProperties | undefined,
overrideProperties?: DevToolsProperties | undefined,
): DevToolsProperties {
return objToPropertiesPayload({
...Object.fromEntries(
(baseProperties ?? []).map(([key, value]) => [key, String(value)]),
),
...Object.fromEntries(
(overrideProperties ?? []).map(([key, value]) => [key, String(value)]),
Comment thread
BioPhoton marked this conversation as resolved.
Outdated
),
});
}

export function markerPayload(
options?: Omit<MarkerPayload, 'dataType'>,
): MarkerPayload {
return {
dataType: dataTypeMarker,
...options,
};
}

export function trackEntryPayload(
options: Omit<TrackEntryPayload, 'dataType'>,
): TrackEntryPayload {
const { track, ...rest } = options;
return {
dataType: dataTypeTrackEntry,
track,
...rest,
};
}

export function markerErrorPayload<T extends DevToolsColor>(
options?: Omit<MarkerPayload, 'dataType' | 'color'>,
): MarkerPayload {
return {
dataType: dataTypeMarker,
color: 'error' as T,
...options,
} satisfies MarkerPayload;
}

export function trackEntryErrorPayload<
T extends string,
C extends DevToolsColor,
>(
options: Omit<TrackEntryPayload, 'color' | 'dataType'> & {
track: T;
color?: C;
},
): TrackEntryPayload {
const { track, color = 'error', ...restOptions } = options;
return {
dataType: dataTypeTrackEntry,
color,
track,
...restOptions,
} satisfies TrackEntryPayload;
}

export function errorToDevToolsProperties(e: unknown): DevToolsProperties {
const name = e instanceof Error ? e.name : 'UnknownError';
const message = e instanceof Error ? e.message : String(e);
return [
['Error Type', name],
['Error Message', message],
];
}

export function errorToEntryMeta(
e: unknown,
options?: {
tooltipText?: string;
properties?: DevToolsProperties;
},
): EntryMeta {
const { properties, tooltipText } = options ?? {};
const props = mergePropertiesWithOverwrite(
errorToDevToolsProperties(e),
properties,
);
return {
properties: props,
...(tooltipText ? { tooltipText } : {}),
};
}

export function errorToTrackEntryPayload<T extends string>(
error: unknown,
detail: Omit<TrackEntryPayload, 'color' | 'dataType'> & {
track: T;
},
) {
const { properties, tooltipText, ...trackPayload } = detail;
return {
dataType: dataTypeTrackEntry,
color: 'error' as const,
...trackPayload,
...errorToEntryMeta(error, {
properties,
tooltipText,
}),
} satisfies TrackEntryPayload;
}

export function errorToMarkerPayload<T extends DevToolsColor>(
error: unknown,
detail?: Omit<MarkerPayload, 'color' | 'dataType'>,
): MarkerPayload {
const { properties, tooltipText } = detail ?? {};
return {
dataType: dataTypeMarker,
color: 'error' as T,
...errorToEntryMeta(error, {
properties,
tooltipText,
}),
} satisfies MarkerPayload;
}

/**
*
* @example
* profiler.mark('mark', asOptions({
* properties: [
* ['str', 'This is a detail property'],
* ['num', 42],
* ['object', { str: '42', num: 42 }],
* ['array', [42, 42, 42]],
* ],
* }));
*/
export function asOptions(
devtools: MarkerPayload,
): Pick<MarkOptionsWithDevtools, 'detail'>;
export function asOptions(
devtools: TrackEntryPayload,
): Pick<MeasureOptionsWithDevtools, 'detail'>;
export function asOptions(
devtools: MarkerPayload | TrackEntryPayload,
):
| Pick<MarkOptionsWithDevtools, 'detail'>
| Pick<MeasureOptionsWithDevtools, 'detail'> {
return devtools ? { detail: { devtools } } : { detail: {} };
}
Comment thread
BioPhoton marked this conversation as resolved.
Outdated
Loading