返回 DeepSeek-Reasonix
diagnostics.ts
根目录 / desktop / electron / src / main / browser / diagnostics.ts
1 export interface PageDiagnostic { sequence: number; time: number; kind: "console" | "exception" | "network" | "navigation"; message: string; url?: string; status?: number }
2
3 export function diagnosticURL(value: string): string {
4 try { const url = new URL(value); if (url.protocol !== "http:" && url.protocol !== "https:") return ""; url.username = ""; url.password = ""; url.search = ""; url.hash = ""; return url.href.slice(0, 1024); }
5 catch { return ""; }
6 }
7 export function diagnosticText(value: string): string {
8 return value.slice(0, 4096)
9 .replace(/https?:\/\/[^\s"'<>]+/gi, diagnosticURL)
10 .replace(/((?:authorization|set-cookie|cookie)["']?\s*[:=]\s*)[^\r\n]*/gi, "$1[redacted]")
11 .replace(/(password|secret|token|api[-_]?key)["']?\s*[:=]\s*(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,;]+)/gi, "$1=[redacted]")
12 .replace(/Bearer\s+[^\s,;]+/gi, "Bearer [redacted]");
13 }
14
15 export class DiagnosticBuffer {
16 private entries: PageDiagnostic[] = [];
17 private sequence = 0;
18 private bytes = 0;
19 private readonly listeners = new Set<(entry: PageDiagnostic) => void>();
20 subscribe(listener: (entry: PageDiagnostic) => void): () => void { this.listeners.add(listener); return () => { this.listeners.delete(listener); }; }
21 add(entry: Omit<PageDiagnostic, "sequence" | "time">): void {
22 const item = { ...entry, sequence: ++this.sequence, time: Date.now(), message: diagnosticText(entry.message), url: entry.url ? diagnosticURL(entry.url) : undefined };
23 this.entries.push(item);
24 this.bytes += Buffer.byteLength(JSON.stringify(item));
25 while (this.entries.length > 200 || this.bytes > 256 * 1024) this.bytes -= Buffer.byteLength(JSON.stringify(this.entries.shift()));
26 for (const listener of this.listeners) listener(item);
27 }
28 read(after = 0, kind = "") { return { available: true, cursor: this.sequence, truncated: after < (this.entries[0]?.sequence ?? 1) - 1, entries: this.entries.filter(entry => entry.sequence > after && (!kind || entry.kind === kind)) }; }
29 }
30
30 lines TYPESCRIPT