99 lines
3.0 KiB
TypeScript
99 lines
3.0 KiB
TypeScript
// file: crates/apps/game-reflex-poc-tauri/frontend/ts/logging.ts
|
|
// version: 2
|
|
|
|
import { attachConsole } from "@fltsci/tauri-plugin-tracing";
|
|
import { invoke } from "@tauri-apps/api/core";
|
|
|
|
export type FrontendLogLevel = "trace" | "debug" | "info" | "warn" | "error";
|
|
export type FrontendLogTarget = "frontend" | "main";
|
|
|
|
type ConsoleMethod = (...items: unknown[]) => void;
|
|
|
|
const originalConsole = {
|
|
trace: console.trace.bind(console),
|
|
debug: console.debug.bind(console),
|
|
info: console.info.bind(console),
|
|
warn: console.warn.bind(console),
|
|
error: console.error.bind(console),
|
|
};
|
|
|
|
function stringifyItem(item: unknown): string {
|
|
if (item instanceof Error) {
|
|
return item.stack ?? item.message;
|
|
}
|
|
if (typeof item === "string") {
|
|
return item;
|
|
}
|
|
try {
|
|
const serialized = JSON.stringify(item);
|
|
return serialized ?? String(item);
|
|
} catch {
|
|
return String(item);
|
|
}
|
|
}
|
|
|
|
function formatMessage(items: unknown[]): string {
|
|
return items.map(item => stringifyItem(item)).join(" ");
|
|
}
|
|
|
|
async function sendFrontendLog(level: FrontendLogLevel, targetId: FrontendLogTarget, message: string): Promise<void> {
|
|
await invoke("emit_frontend_log", {
|
|
payload: {
|
|
level,
|
|
targetId,
|
|
message,
|
|
},
|
|
});
|
|
}
|
|
|
|
function originalConsoleFor(level: FrontendLogLevel): ConsoleMethod {
|
|
return level === "trace"
|
|
? originalConsole.trace
|
|
: level === "debug"
|
|
? originalConsole.debug
|
|
: level === "info"
|
|
? originalConsole.info
|
|
: level === "warn"
|
|
? originalConsole.warn
|
|
: originalConsole.error;
|
|
}
|
|
|
|
export async function initializeTracing(): Promise<void> {
|
|
await attachConsole();
|
|
await emitFrontendLog("info", "main", "Reflex Tauri frontend tracing initialized");
|
|
}
|
|
|
|
export async function emitFrontendLog(level: FrontendLogLevel, targetId: FrontendLogTarget, ...items: unknown[]): Promise<void> {
|
|
const message = formatMessage(items);
|
|
originalConsoleFor(level)(message);
|
|
await sendFrontendLog(level, targetId, message);
|
|
}
|
|
|
|
function emitDetached(level: FrontendLogLevel, targetId: FrontendLogTarget, items: unknown[]): void {
|
|
const message = formatMessage(items);
|
|
originalConsoleFor(level)(message);
|
|
void sendFrontendLog(level, targetId, message).catch(caughtError => {
|
|
originalConsole.error("Reflex frontend logging bridge failed", caughtError);
|
|
});
|
|
}
|
|
|
|
export function tracingTrace(...items: unknown[]): void {
|
|
emitDetached("trace", "frontend", items);
|
|
}
|
|
|
|
export function tracingDebug(...items: unknown[]): void {
|
|
emitDetached("debug", "frontend", items);
|
|
}
|
|
|
|
export function tracingInfo(...items: unknown[]): void {
|
|
emitDetached("info", "frontend", items);
|
|
}
|
|
|
|
export function tracingWarn(...items: unknown[]): void {
|
|
emitDetached("warn", "frontend", items);
|
|
}
|
|
|
|
export function tracingError(...items: unknown[]): void {
|
|
emitDetached("error", "frontend", items);
|
|
}
|