Files
Toju/electron/diagnostics/high-memory-alert.store.ts
Myx bb0ac930ad
All checks were successful
Queue Release Build / prepare (push) Successful in 20s
Deploy Web Apps / deploy (push) Successful in 9m2s
Queue Release Build / build-windows (push) Successful in 28m8s
Queue Release Build / build-linux (push) Successful in 47m26s
Queue Release Build / build-android (push) Successful in 19m52s
Queue Release Build / finalize (push) Successful in 4m42s
Improve attachment memory safety, downloads, and high-memory alert UX.
Stream large receives to disk with chunk acks to cap renderer RAM, evict
off-screen display blobs, and route exports through a disk-aware download
service. Fix the high-memory dialog (backdrop dismiss, copy, log actions),
allow diagnostics paths in the path jail, and restore persisted image
hydration after reload.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 00:25:22 +02:00

64 lines
1.8 KiB
TypeScript

import * as fsp from 'fs/promises';
import * as path from 'path';
export type HighMemoryAlertReason = 'manual' | 'threshold';
export interface HighMemoryAlertRecord {
logFilePath: string;
detectedAt: number;
peakWorkingSetKb: number;
sessionId: string;
reason?: HighMemoryAlertReason;
}
export function resolveHighMemoryAlertPath(userDataPath: string): string {
return path.join(userDataPath, 'diagnostics', 'high-memory-pending.json');
}
export async function readHighMemoryAlert(userDataPath: string): Promise<HighMemoryAlertRecord | null> {
try {
const raw = await fsp.readFile(resolveHighMemoryAlertPath(userDataPath), 'utf8');
const parsed = JSON.parse(raw) as Partial<HighMemoryAlertRecord>;
if (
typeof parsed.logFilePath !== 'string'
|| !parsed.logFilePath.trim()
|| typeof parsed.detectedAt !== 'number'
|| typeof parsed.peakWorkingSetKb !== 'number'
|| typeof parsed.sessionId !== 'string'
) {
return null;
}
return {
logFilePath: parsed.logFilePath,
detectedAt: parsed.detectedAt,
peakWorkingSetKb: parsed.peakWorkingSetKb,
sessionId: parsed.sessionId,
...(parsed.reason === 'manual' || parsed.reason === 'threshold'
? { reason: parsed.reason }
: {})
};
} catch {
return null;
}
}
export async function writeHighMemoryAlert(
userDataPath: string,
record: HighMemoryAlertRecord
): Promise<void> {
const filePath = resolveHighMemoryAlertPath(userDataPath);
await fsp.mkdir(path.dirname(filePath), { recursive: true });
await fsp.writeFile(filePath, `${JSON.stringify(record, null, 2)}\n`, 'utf8');
}
export async function clearHighMemoryAlert(userDataPath: string): Promise<void> {
try {
await fsp.unlink(resolveHighMemoryAlertPath(userDataPath));
} catch {
// Missing pending alert is fine.
}
}