返回 DeepSeek-Reasonix
breadcrumbs.ts
根目录 / desktop / frontend / src / lib / breadcrumbs.ts
1 // A small ring buffer of recent app events, attached to crash reports so a stack
2 // trace arrives with the steps that led to it. Self-contained (no app imports) so
3 // the crash overlay can read it even when the rest of the app is broken.
4
5 export type Breadcrumb = { t: number; cat: string; msg: string };
6
7 const MAX = 30;
8 const ring: Breadcrumb[] = [];
9 let browserHooksInstalled = false;
10
11 export function addBreadcrumb(cat: string, msg: string): void {
12 ring.push({ t: Date.now(), cat, msg: msg.length > 200 ? `${msg.slice(0, 200)}…` : msg });
13 if (ring.length > MAX) ring.shift();
14 }
15
16 export function snapshotBreadcrumbs(): Breadcrumb[] {
17 return ring.map((b) => ({ ...b }));
18 }
19
20 export function dumpBreadcrumbs(): string {
21 if (!ring.length) return "";
22 const now = Date.now();
23 return ring.map((b) => `-${((now - b.t) / 1000).toFixed(1)}s [${b.cat}] ${b.msg}`).join("\n");
24 }
25
26 function stringifyArg(a: unknown): string {
27 if (typeof a === "string") return a;
28 if (a instanceof Error) return a.message;
29 try {
30 return JSON.stringify(a);
31 } catch {
32 return String(a);
33 }
34 }
35
36 export function installBreadcrumbConsoleHook(): void {
37 if (!browserHooksInstalled) {
38 browserHooksInstalled = true;
39 addBreadcrumb("app", "start");
40 if (typeof window !== "undefined") {
41 window.addEventListener("online", () => addBreadcrumb("network", "online"));
42 window.addEventListener("offline", () => addBreadcrumb("network", "offline"));
43 document.addEventListener("visibilitychange", () => addBreadcrumb("view", document.visibilityState));
44 }
45 }
46 for (const level of ["error", "warn"] as const) {
47 const orig = console[level].bind(console);
48 console[level] = (...args: unknown[]) => {
49 addBreadcrumb(`console.${level}`, args.map(stringifyArg).join(" "));
50 orig(...args);
51 };
52 }
53 }
54
54 lines TYPESCRIPT