mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
Update TaskManagerTab.tsx
This commit is contained in:
parent
3c8b9d107b
commit
24688c3104
@ -23,14 +23,17 @@ interface BatteryManager extends EventTarget {
|
|||||||
level: number;
|
level: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProcessStatus = 'active' | 'idle' | 'suspended';
|
||||||
|
type ProcessImpact = 'high' | 'medium' | 'low';
|
||||||
|
|
||||||
interface ProcessInfo {
|
interface ProcessInfo {
|
||||||
name: string;
|
name: string;
|
||||||
type: 'API' | 'Animation' | 'Background' | 'Render' | 'Network' | 'Storage';
|
type: 'API' | 'Animation' | 'Background' | 'Network' | 'Storage';
|
||||||
cpuUsage: number;
|
cpuUsage: number;
|
||||||
memoryUsage: number;
|
memoryUsage: number;
|
||||||
status: 'active' | 'idle' | 'suspended';
|
status: ProcessStatus;
|
||||||
lastUpdate: string;
|
lastUpdate: string;
|
||||||
impact: 'high' | 'medium' | 'low';
|
impact: ProcessImpact;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SystemMetrics {
|
interface SystemMetrics {
|
||||||
@ -141,6 +144,8 @@ export default function TaskManagerTab() {
|
|||||||
|
|
||||||
const saverModeStartTime = useRef<number | null>(null);
|
const saverModeStartTime = useRef<number | null>(null);
|
||||||
|
|
||||||
|
const [performanceObserver, setPerformanceObserver] = useState<PerformanceObserver | null>(null);
|
||||||
|
|
||||||
// Handle energy saver mode changes
|
// Handle energy saver mode changes
|
||||||
const handleEnergySaverChange = (checked: boolean) => {
|
const handleEnergySaverChange = (checked: boolean) => {
|
||||||
setEnergySaverMode(checked);
|
setEnergySaverMode(checked);
|
||||||
@ -161,10 +166,64 @@ export default function TaskManagerTab() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate energy savings
|
// Add this helper function at the top level of the component
|
||||||
|
function isNetworkRequest(entry: PerformanceEntry): boolean {
|
||||||
|
const resourceTiming = entry as PerformanceResourceTiming;
|
||||||
|
return resourceTiming.initiatorType === 'fetch' && entry.duration === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update getActiveProcessCount
|
||||||
|
const getActiveProcessCount = async (): Promise<number> => {
|
||||||
|
try {
|
||||||
|
const networkCount = (navigator as any)?.connections?.length || 0;
|
||||||
|
const swCount = (await navigator.serviceWorker?.getRegistrations().then((regs) => regs.length)) || 0;
|
||||||
|
const animationCount = document.getAnimations().length;
|
||||||
|
const fetchCount = performance.getEntriesByType('resource').filter(isNetworkRequest).length;
|
||||||
|
|
||||||
|
return networkCount + swCount + animationCount + fetchCount;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to get active process count:', error);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update process cleanup
|
||||||
|
const cleanupOldProcesses = useCallback(() => {
|
||||||
|
const MAX_PROCESS_AGE = 30000; // 30 seconds
|
||||||
|
|
||||||
|
setProcesses((currentProcesses) => {
|
||||||
|
const now = Date.now();
|
||||||
|
return currentProcesses.filter((process) => {
|
||||||
|
const processTime = new Date(process.lastUpdate).getTime();
|
||||||
|
const age = now - processTime;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keep processes that are:
|
||||||
|
* 1. Less than MAX_PROCESS_AGE old, or
|
||||||
|
* 2. Currently active, or
|
||||||
|
* 3. Service workers (they're managed separately)
|
||||||
|
*/
|
||||||
|
return age < MAX_PROCESS_AGE || process.status === 'active' || process.type === 'Background';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Add cleanup interval
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(cleanupOldProcesses, 5000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [cleanupOldProcesses]);
|
||||||
|
|
||||||
|
// Update energy savings calculation
|
||||||
const updateEnergySavings = useCallback(() => {
|
const updateEnergySavings = useCallback(() => {
|
||||||
if (!energySaverMode) {
|
if (!energySaverMode) {
|
||||||
saverModeStartTime.current = null;
|
saverModeStartTime.current = null;
|
||||||
|
setEnergySavings({
|
||||||
|
updatesReduced: 0,
|
||||||
|
timeInSaverMode: 0,
|
||||||
|
estimatedEnergySaved: 0,
|
||||||
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,42 +231,75 @@ export default function TaskManagerTab() {
|
|||||||
saverModeStartTime.current = Date.now();
|
saverModeStartTime.current = Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeInSaverMode = (Date.now() - saverModeStartTime.current) / 1000; // in seconds
|
const timeInSaverMode = Math.max(0, (Date.now() - (saverModeStartTime.current || Date.now())) / 1000);
|
||||||
const normalUpdatesPerMinute =
|
|
||||||
60 / (UPDATE_INTERVALS.normal.metrics / 1000) + 60 / (UPDATE_INTERVALS.normal.processes / 1000);
|
const normalUpdatesPerMinute = 60 / (UPDATE_INTERVALS.normal.metrics / 1000);
|
||||||
const saverUpdatesPerMinute =
|
const saverUpdatesPerMinute = 60 / (UPDATE_INTERVALS.energySaver.metrics / 1000);
|
||||||
60 / (UPDATE_INTERVALS.energySaver.metrics / 1000) + 60 / (UPDATE_INTERVALS.energySaver.processes / 1000);
|
|
||||||
const updatesReduced = Math.floor((normalUpdatesPerMinute - saverUpdatesPerMinute) * (timeInSaverMode / 60));
|
const updatesReduced = Math.floor((normalUpdatesPerMinute - saverUpdatesPerMinute) * (timeInSaverMode / 60));
|
||||||
|
|
||||||
// Calculate energy saved (mWh)
|
const processCount = processes.length;
|
||||||
const energySaved =
|
const energyPerUpdate = ENERGY_COSTS.update + processCount * ENERGY_COSTS.rendering;
|
||||||
(updatesReduced * ENERGY_COSTS.update + // Energy saved from reduced updates
|
const energySaved = (updatesReduced * energyPerUpdate) / 3600;
|
||||||
updatesReduced * ENERGY_COSTS.apiCall + // Energy saved from fewer API calls
|
|
||||||
updatesReduced * ENERGY_COSTS.rendering) / // Energy saved from fewer renders
|
|
||||||
3600; // Convert to watt-hours (divide by 3600 seconds)
|
|
||||||
|
|
||||||
setEnergySavings({
|
setEnergySavings({
|
||||||
updatesReduced,
|
updatesReduced,
|
||||||
timeInSaverMode,
|
timeInSaverMode,
|
||||||
estimatedEnergySaved: energySaved,
|
estimatedEnergySaved: energySaved,
|
||||||
});
|
});
|
||||||
}, [energySaverMode]);
|
}, [energySaverMode, processes.length]);
|
||||||
|
|
||||||
useEffect((): (() => void) | undefined => {
|
// Add interval for energy savings updates
|
||||||
if (!energySaverMode) {
|
useEffect(() => {
|
||||||
// Clear any existing intervals and reset savings when disabled
|
const interval = setInterval(updateEnergySavings, 1000);
|
||||||
setEnergySavings({
|
return () => clearInterval(interval);
|
||||||
updatesReduced: 0,
|
}, [updateEnergySavings]);
|
||||||
timeInSaverMode: 0,
|
|
||||||
estimatedEnergySaved: 0,
|
// Improve process monitoring by adding unique IDs and timestamps
|
||||||
|
const createProcess = (
|
||||||
|
name: string,
|
||||||
|
type: ProcessInfo['type'],
|
||||||
|
cpuUsage: number,
|
||||||
|
memoryUsage: number,
|
||||||
|
status: ProcessStatus,
|
||||||
|
impact: ProcessImpact,
|
||||||
|
): ProcessInfo => ({
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
cpuUsage,
|
||||||
|
memoryUsage,
|
||||||
|
status,
|
||||||
|
lastUpdate: new Date().toISOString(),
|
||||||
|
impact,
|
||||||
});
|
});
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const savingsInterval = setInterval(updateEnergySavings, 1000);
|
// Update animation monitoring to track changes better
|
||||||
|
const updateAnimations = useCallback(() => {
|
||||||
|
const animations = document.getAnimations();
|
||||||
|
|
||||||
return () => clearInterval(savingsInterval);
|
setProcesses((currentProcesses) => {
|
||||||
}, [energySaverMode, updateEnergySavings]);
|
const nonAnimationProcesses = currentProcesses.filter((p) => !p.name.startsWith('Animation:'));
|
||||||
|
const newAnimations = animations
|
||||||
|
.slice(0, 5)
|
||||||
|
.map((animation) =>
|
||||||
|
createProcess(
|
||||||
|
`Animation: ${animation.id || 'Unnamed'}`,
|
||||||
|
'Animation',
|
||||||
|
animation.playState === 'running' ? 2 : 0,
|
||||||
|
1,
|
||||||
|
animation.playState === 'running' ? 'active' : 'idle',
|
||||||
|
'low',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return [...nonAnimationProcesses, ...newAnimations];
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Add animation monitoring interval
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(updateAnimations, energySaverMode ? 5000 : 1000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [updateAnimations, energySaverMode]);
|
||||||
|
|
||||||
useEffect((): (() => void) | undefined => {
|
useEffect((): (() => void) | undefined => {
|
||||||
if (!autoEnergySaver) {
|
if (!autoEnergySaver) {
|
||||||
@ -245,7 +337,7 @@ export default function TaskManagerTab() {
|
|||||||
return 'text-gray-500';
|
return 'text-gray-500';
|
||||||
};
|
};
|
||||||
|
|
||||||
const getImpactColor = (impact: 'high' | 'medium' | 'low'): string => {
|
const getImpactColor = (impact: ProcessImpact): string => {
|
||||||
if (impact === 'high') {
|
if (impact === 'high') {
|
||||||
return 'text-red-500';
|
return 'text-red-500';
|
||||||
}
|
}
|
||||||
@ -382,77 +474,196 @@ export default function TaskManagerTab() {
|
|||||||
const getCPUUsage = async (): Promise<number> => {
|
const getCPUUsage = async (): Promise<number> => {
|
||||||
try {
|
try {
|
||||||
const t0 = performance.now();
|
const t0 = performance.now();
|
||||||
const startEntries = performance.getEntriesByType('measure');
|
|
||||||
|
|
||||||
// Wait a short time to measure CPU usage
|
// Create some actual work to measure and use the result
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
let result = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < 10000; i++) {
|
||||||
|
result += Math.random();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use result to prevent optimization
|
||||||
|
if (result < 0) {
|
||||||
|
console.log('Unexpected negative result');
|
||||||
|
}
|
||||||
|
|
||||||
const t1 = performance.now();
|
const t1 = performance.now();
|
||||||
const endEntries = performance.getEntriesByType('measure');
|
const timeTaken = t1 - t0;
|
||||||
|
|
||||||
// Calculate CPU usage based on the number of performance entries
|
/*
|
||||||
const entriesPerMs = (endEntries.length - startEntries.length) / (t1 - t0);
|
* Normalize to percentage (0-100)
|
||||||
|
* Lower time = higher CPU availability
|
||||||
|
*/
|
||||||
|
const maxExpectedTime = 50; // baseline in ms
|
||||||
|
const cpuAvailability = Math.max(0, Math.min(100, ((maxExpectedTime - timeTaken) / maxExpectedTime) * 100));
|
||||||
|
|
||||||
// Normalize to percentage (0-100)
|
return 100 - cpuAvailability; // Convert availability to usage
|
||||||
return Math.min(100, entriesPerMs * 1000);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to get CPU usage:', error);
|
console.error('Failed to get CPU usage:', error);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get real active process count
|
// Add network change listener
|
||||||
const getActiveProcessCount = async (): Promise<number> => {
|
useEffect(() => {
|
||||||
try {
|
const connection =
|
||||||
// Count active network connections
|
(navigator as any).connection || (navigator as any).mozConnection || (navigator as any).webkitConnection;
|
||||||
const networkCount = (navigator as any)?.connections?.length || 0;
|
|
||||||
|
|
||||||
// Count active service workers
|
if (!connection) {
|
||||||
const swCount = (await navigator.serviceWorker?.getRegistrations().then((regs) => regs.length)) || 0;
|
return;
|
||||||
|
|
||||||
// Count active animations
|
|
||||||
const animationCount = document.getAnimations().length;
|
|
||||||
|
|
||||||
// Count active fetch requests
|
|
||||||
const fetchCount = performance
|
|
||||||
.getEntriesByType('resource')
|
|
||||||
.filter(
|
|
||||||
(entry) => (entry as PerformanceResourceTiming).initiatorType === 'fetch' && entry.duration === 0,
|
|
||||||
).length;
|
|
||||||
|
|
||||||
return networkCount + swCount + animationCount + fetchCount;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to get active process count:', error);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateNetworkInfo = () => {
|
||||||
|
setMetrics((prev) => ({
|
||||||
|
...prev,
|
||||||
|
network: {
|
||||||
|
downlink: connection.downlink || 0,
|
||||||
|
latency: connection.rtt || 0,
|
||||||
|
type: connection.type || 'unknown',
|
||||||
|
},
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
connection.addEventListener('change', updateNetworkInfo);
|
||||||
|
|
||||||
|
// eslint-disable-next-line consistent-return
|
||||||
|
return () => connection.removeEventListener('change', updateNetworkInfo);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Add this effect for live process monitoring
|
||||||
|
useEffect(() => {
|
||||||
|
// Clean up previous observer if exists
|
||||||
|
performanceObserver?.disconnect();
|
||||||
|
|
||||||
|
// Create new performance observer for network requests
|
||||||
|
const observer = new PerformanceObserver((list) => {
|
||||||
|
const entries = list.getEntries();
|
||||||
|
const newNetworkEntries = entries
|
||||||
|
.filter((entry: PerformanceEntry): boolean => {
|
||||||
|
const resourceTiming = entry as PerformanceResourceTiming;
|
||||||
|
return entry.entryType === 'resource' && resourceTiming.initiatorType === 'fetch';
|
||||||
|
})
|
||||||
|
.slice(-5);
|
||||||
|
|
||||||
|
if (newNetworkEntries.length > 0) {
|
||||||
|
setProcesses((currentProcesses) => {
|
||||||
|
// Remove old network processes
|
||||||
|
const filteredProcesses = currentProcesses.filter((p) => !p.name.startsWith('Network Request:'));
|
||||||
|
|
||||||
|
// Add new network processes
|
||||||
|
const newProcesses = newNetworkEntries.map((entry) => ({
|
||||||
|
name: `Network Request: ${new URL((entry as PerformanceResourceTiming).name).pathname}`,
|
||||||
|
type: 'Network' as const,
|
||||||
|
cpuUsage: entry.duration > 0 ? entry.duration / 100 : 0,
|
||||||
|
memoryUsage: (entry as PerformanceResourceTiming).encodedBodySize / (1024 * 1024),
|
||||||
|
status: (entry.duration === 0 ? 'active' : 'idle') as ProcessStatus,
|
||||||
|
lastUpdate: new Date().toISOString(),
|
||||||
|
impact: (entry.duration > 1000 ? 'high' : entry.duration > 500 ? 'medium' : 'low') as ProcessImpact,
|
||||||
|
})) as ProcessInfo[];
|
||||||
|
|
||||||
|
return [...filteredProcesses, ...newProcesses];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start observing resource timing entries
|
||||||
|
observer.observe({ entryTypes: ['resource'] });
|
||||||
|
setPerformanceObserver(observer);
|
||||||
|
|
||||||
|
// Set up animation observer
|
||||||
|
const animationObserver = new MutationObserver(() => {
|
||||||
|
const animations = document.getAnimations();
|
||||||
|
|
||||||
|
setProcesses((currentProcesses) => {
|
||||||
|
// Remove old animation processes
|
||||||
|
const filteredProcesses = currentProcesses.filter((p) => !p.name.startsWith('Animation:'));
|
||||||
|
|
||||||
|
// Add current animations
|
||||||
|
const animationProcesses = animations.slice(0, 5).map((animation) => ({
|
||||||
|
name: `Animation: ${animation.id || 'Unnamed'}`,
|
||||||
|
type: 'Animation' as const,
|
||||||
|
cpuUsage: animation.playState === 'running' ? 2 : 0,
|
||||||
|
memoryUsage: 1,
|
||||||
|
status: (animation.playState === 'running' ? 'active' : 'idle') as ProcessStatus,
|
||||||
|
lastUpdate: new Date().toISOString(),
|
||||||
|
impact: 'low' as ProcessImpact,
|
||||||
|
})) as ProcessInfo[];
|
||||||
|
|
||||||
|
return [...filteredProcesses, ...animationProcesses];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Observe DOM changes that might trigger animations
|
||||||
|
animationObserver.observe(document.body, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
attributes: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set up service worker observer
|
||||||
|
const checkServiceWorkers = async () => {
|
||||||
|
const serviceWorkers = (await navigator.serviceWorker?.getRegistrations()) || [];
|
||||||
|
|
||||||
|
setProcesses((currentProcesses) => {
|
||||||
|
// Remove old service worker processes
|
||||||
|
const filteredProcesses = currentProcesses.filter((p) => !p.name.startsWith('Service Worker:'));
|
||||||
|
|
||||||
|
// Add current service workers
|
||||||
|
const swProcesses = serviceWorkers.map((sw) => ({
|
||||||
|
name: `Service Worker: ${sw.scope}`,
|
||||||
|
type: 'Background' as const,
|
||||||
|
cpuUsage: sw.active ? 1 : 0,
|
||||||
|
memoryUsage: 5,
|
||||||
|
status: (sw.active ? 'active' : 'idle') as ProcessStatus,
|
||||||
|
lastUpdate: new Date().toISOString(),
|
||||||
|
impact: 'low' as ProcessImpact,
|
||||||
|
})) as ProcessInfo[];
|
||||||
|
|
||||||
|
return [...filteredProcesses, ...swProcesses];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check service workers periodically
|
||||||
|
const swInterval = setInterval(checkServiceWorkers, 5000);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
return () => {
|
||||||
|
performanceObserver?.disconnect();
|
||||||
|
animationObserver.disconnect();
|
||||||
|
clearInterval(swInterval);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Update the updateProcesses function
|
||||||
const updateProcesses = async () => {
|
const updateProcesses = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading((prev) => ({ ...prev, processes: true }));
|
setLoading((prev) => ({ ...prev, processes: true }));
|
||||||
|
|
||||||
// Get real process information
|
// Get initial process information
|
||||||
const processes: ProcessInfo[] = [];
|
const processes: ProcessInfo[] = [];
|
||||||
|
|
||||||
// Add network processes
|
// Add initial network processes
|
||||||
const networkEntries = performance
|
const networkEntries = performance
|
||||||
.getEntriesByType('resource')
|
.getEntriesByType('resource')
|
||||||
.filter((entry) => (entry as PerformanceResourceTiming).initiatorType === 'fetch' && entry.duration === 0)
|
.filter((entry: PerformanceEntry): boolean => {
|
||||||
.slice(-5); // Get last 5 active requests
|
const resourceTiming = entry as PerformanceResourceTiming;
|
||||||
|
return entry.entryType === 'resource' && resourceTiming.initiatorType === 'fetch';
|
||||||
|
})
|
||||||
|
.slice(-5);
|
||||||
|
|
||||||
networkEntries.forEach((entry) => {
|
networkEntries.forEach((entry) => {
|
||||||
processes.push({
|
processes.push({
|
||||||
name: `Network Request: ${new URL((entry as PerformanceResourceTiming).name).pathname}`,
|
name: `Network Request: ${new URL((entry as PerformanceResourceTiming).name).pathname}`,
|
||||||
type: 'Network',
|
type: 'Network',
|
||||||
cpuUsage: entry.duration > 0 ? entry.duration / 100 : 0,
|
cpuUsage: entry.duration > 0 ? entry.duration / 100 : 0,
|
||||||
memoryUsage: (entry as PerformanceResourceTiming).encodedBodySize / (1024 * 1024), // Convert to MB
|
memoryUsage: (entry as PerformanceResourceTiming).encodedBodySize / (1024 * 1024),
|
||||||
status: entry.duration === 0 ? 'active' : 'idle',
|
status: (entry.duration === 0 ? 'active' : 'idle') as ProcessStatus,
|
||||||
lastUpdate: new Date().toISOString(),
|
lastUpdate: new Date().toISOString(),
|
||||||
impact: entry.duration > 1000 ? 'high' : entry.duration > 500 ? 'medium' : 'low',
|
impact: (entry.duration > 1000 ? 'high' : entry.duration > 500 ? 'medium' : 'low') as ProcessImpact,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add animation processes
|
// Add initial animations
|
||||||
document
|
document
|
||||||
.getAnimations()
|
.getAnimations()
|
||||||
.slice(0, 5)
|
.slice(0, 5)
|
||||||
@ -461,24 +672,24 @@ export default function TaskManagerTab() {
|
|||||||
name: `Animation: ${animation.id || 'Unnamed'}`,
|
name: `Animation: ${animation.id || 'Unnamed'}`,
|
||||||
type: 'Animation',
|
type: 'Animation',
|
||||||
cpuUsage: animation.playState === 'running' ? 2 : 0,
|
cpuUsage: animation.playState === 'running' ? 2 : 0,
|
||||||
memoryUsage: 1, // Approximate memory usage
|
memoryUsage: 1,
|
||||||
status: animation.playState === 'running' ? 'active' : 'idle',
|
status: (animation.playState === 'running' ? 'active' : 'idle') as ProcessStatus,
|
||||||
lastUpdate: new Date().toISOString(),
|
lastUpdate: new Date().toISOString(),
|
||||||
impact: 'low',
|
impact: 'low' as ProcessImpact,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add service worker processes
|
// Add initial service workers
|
||||||
const serviceWorkers = (await navigator.serviceWorker?.getRegistrations()) || [];
|
const serviceWorkers = (await navigator.serviceWorker?.getRegistrations()) || [];
|
||||||
serviceWorkers.forEach((sw) => {
|
serviceWorkers.forEach((sw) => {
|
||||||
processes.push({
|
processes.push({
|
||||||
name: `Service Worker: ${sw.scope}`,
|
name: `Service Worker: ${sw.scope}`,
|
||||||
type: 'Background',
|
type: 'Background',
|
||||||
cpuUsage: sw.active ? 1 : 0,
|
cpuUsage: sw.active ? 1 : 0,
|
||||||
memoryUsage: 5, // Approximate memory usage
|
memoryUsage: 5,
|
||||||
status: sw.active ? 'active' : 'idle',
|
status: (sw.active ? 'active' : 'idle') as ProcessStatus,
|
||||||
lastUpdate: new Date().toISOString(),
|
lastUpdate: new Date().toISOString(),
|
||||||
impact: 'low',
|
impact: 'low' as ProcessImpact,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user