Simpl-Resultat/src/services/logService.ts
le king fu fb92cfc12c
All checks were successful
Release / build-and-release (push) Successful in 25m5s
Add startup retry logic and persist logs across refresh
Retry connectActiveProfile up to 3 times with 1s delay before showing
the error page. Persist log buffer to sessionStorage so logs survive
page refresh and are visible in the settings log viewer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 22:12:41 -05:00

98 lines
2 KiB
TypeScript

export type LogLevel = "info" | "warn" | "error";
export interface LogEntry {
timestamp: number;
level: LogLevel;
message: string;
}
type LogListener = () => void;
const MAX_ENTRIES = 500;
const STORAGE_KEY = "simpl-resultat-logs";
const logs: LogEntry[] = [];
const listeners = new Set<LogListener>();
let initialized = false;
function loadFromStorage() {
try {
const stored = sessionStorage.getItem(STORAGE_KEY);
if (stored) {
const parsed: LogEntry[] = JSON.parse(stored);
logs.push(...parsed);
}
} catch {
// ignore corrupted storage
}
}
function saveToStorage() {
try {
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(logs));
} catch {
// ignore quota errors
}
}
function addEntry(level: LogLevel, args: unknown[]) {
const message = args
.map((a) => {
if (typeof a === "string") return a;
try {
return JSON.stringify(a);
} catch {
return String(a);
}
})
.join(" ");
logs.push({ timestamp: Date.now(), level, message });
if (logs.length > MAX_ENTRIES) {
logs.splice(0, logs.length - MAX_ENTRIES);
}
saveToStorage();
listeners.forEach((fn) => fn());
}
export function initLogCapture() {
if (initialized) return;
initialized = true;
loadFromStorage();
const origLog = console.log.bind(console);
const origWarn = console.warn.bind(console);
const origError = console.error.bind(console);
console.log = (...args: unknown[]) => {
addEntry("info", args);
origLog(...args);
};
console.warn = (...args: unknown[]) => {
addEntry("warn", args);
origWarn(...args);
};
console.error = (...args: unknown[]) => {
addEntry("error", args);
origError(...args);
};
}
export function getLogs(): readonly LogEntry[] {
return logs;
}
export function clearLogs() {
logs.length = 0;
saveToStorage();
listeners.forEach((fn) => fn());
}
export function subscribe(listener: LogListener): () => void {
listeners.add(listener);
return () => listeners.delete(listener);
}