All checks were successful
Release / build-and-release (push) Successful in 25m5s
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>
98 lines
2 KiB
TypeScript
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);
|
|
}
|