1import type { ResourceTelemetryProcess, ResourceTelemetrySourceStatus } from "@t3tools/contracts";
2
3function processIdentityKey(process: ResourceTelemetryProcess): string {
4 return `${process.identity.pid}:${process.identity.startTimeMs}`;
5}
6
7export function visibleResourceTelemetryProcesses(
8 processes: ReadonlyArray<ResourceTelemetryProcess>,
9 collapsed: ReadonlySet<string>,
10): ReadonlyArray<ResourceTelemetryProcess> {
11 const childrenByParent = new Map<number, ResourceTelemetryProcess[]>();
12 for (const process of processes) {
13 const children = childrenByParent.get(process.ppid) ?? [];
14 children.push(process);
15 childrenByParent.set(process.ppid, children);
16 }
17
18 const hidden = new Set<string>();
19 const hideDescendants = (pid: number): void => {
20 for (const child of childrenByParent.get(pid) ?? []) {
21 const key = processIdentityKey(child);
22 if (hidden.has(key)) continue;
23 hidden.add(key);
24 hideDescendants(child.identity.pid);
25 }
26 };
27 for (const process of processes) {
28 if (collapsed.has(processIdentityKey(process))) {
29 hideDescendants(process.identity.pid);
30 }
31 }
32 return processes.filter((process) => !hidden.has(processIdentityKey(process)));
33}
34
35export function shouldShowResourceMonitorRetry(input: {
36 readonly nativeStatus: ResourceTelemetrySourceStatus | null;
37 readonly error: string | null;
38}): boolean {
39 return (
40 (input.nativeStatus === null && input.error !== null) ||
41 input.nativeStatus === "degraded" ||
42 input.nativeStatus === "unavailable" ||
43 input.nativeStatus === "stopped"
44 );
45}
46
47export function resourceHistoryBarHeight(input: {
48 readonly value: number;
49 readonly max: number;
50 readonly minimumVisiblePercent: number;
51}): number {
52 if (input.value <= 0) return 0;
53 return Math.max(input.minimumVisiblePercent, (input.value / Math.max(1, input.max)) * 100);
54}
55
56export function resourceHistoryCpuScaleMax(
57 buckets: ReadonlyArray<{ readonly avgCpuPercent: number }>,
58): number {
59 return Math.max(1, ...buckets.map((bucket) => bucket.avgCpuPercent));
60}