117 lines
4.8 KiB
TypeScript
117 lines
4.8 KiB
TypeScript
// file: crates/ksp-app-raw-transaction-ingest-desk/frontend/ts/frontend_log.ts
|
|
// version: 2
|
|
|
|
import { invoke } from "@tauri-apps/api/core";
|
|
import type { FrontendLogPayloadDto } from "./bindings/ksp_app_raw_transaction_ingest_desk/frontend_logging/FrontendLogPayloadDto.ts";
|
|
|
|
export type FrontendLogLevel = "trace" | "debug" | "info" | "warn" | "error";
|
|
export type FrontendLogTargetId = "frontend" | "main" | "splash";
|
|
|
|
type ConsoleMethod = (...items: unknown[]) => void;
|
|
|
|
const FRONTEND_LOG_MESSAGE_MAX_CODE_UNITS = 1024;
|
|
|
|
const originalConsole = {
|
|
trace: console.trace.bind(console),
|
|
debug: console.debug.bind(console),
|
|
log: console.log.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(" ");
|
|
}
|
|
|
|
function boundMessage(message: string): string {
|
|
return message.length <= FRONTEND_LOG_MESSAGE_MAX_CODE_UNITS ? message : `${message.slice(0, FRONTEND_LOG_MESSAGE_MAX_CODE_UNITS)}…`;
|
|
}
|
|
|
|
async function sendFrontendLog(level: FrontendLogLevel, targetId: FrontendLogTargetId, message: string): Promise<void> {
|
|
const payload: FrontendLogPayloadDto = {
|
|
level,
|
|
targetId,
|
|
message: boundMessage(message),
|
|
};
|
|
await invoke("emit_frontend_log", { payload });
|
|
}
|
|
|
|
function writeOriginalConsole(level: FrontendLogLevel, message: string): void {
|
|
return level === "trace"
|
|
? originalConsole.trace(message)
|
|
: level === "debug"
|
|
? originalConsole.debug(message)
|
|
: level === "info"
|
|
? originalConsole.info(message)
|
|
: level === "warn"
|
|
? originalConsole.warn(message)
|
|
: originalConsole.error(message);
|
|
}
|
|
|
|
export async function emitFrontendLog(level: FrontendLogLevel, targetId: FrontendLogTargetId, message: string): Promise<void> {
|
|
writeOriginalConsole(level, message);
|
|
await sendFrontendLog(level, targetId, message);
|
|
}
|
|
|
|
export function frontendTrace(targetId: FrontendLogTargetId, ...items: unknown[]): void {
|
|
const message = formatMessage(items);
|
|
originalConsole.trace(message);
|
|
void sendFrontendLog("trace", targetId, message).catch(caughtError => originalConsole.error("KSP frontend logging bridge failed", caughtError));
|
|
}
|
|
|
|
export function frontendDebug(targetId: FrontendLogTargetId, ...items: unknown[]): void {
|
|
const message = formatMessage(items);
|
|
originalConsole.debug(message);
|
|
void sendFrontendLog("debug", targetId, message).catch(caughtError => originalConsole.error("KSP frontend logging bridge failed", caughtError));
|
|
}
|
|
|
|
export function frontendInfo(targetId: FrontendLogTargetId, ...items: unknown[]): void {
|
|
const message = formatMessage(items);
|
|
originalConsole.info(message);
|
|
void sendFrontendLog("info", targetId, message).catch(caughtError => originalConsole.error("KSP frontend logging bridge failed", caughtError));
|
|
}
|
|
|
|
export function frontendWarn(targetId: FrontendLogTargetId, ...items: unknown[]): void {
|
|
const message = formatMessage(items);
|
|
originalConsole.warn(message);
|
|
void sendFrontendLog("warn", targetId, message).catch(caughtError => originalConsole.error("KSP frontend logging bridge failed", caughtError));
|
|
}
|
|
|
|
export function frontendError(targetId: FrontendLogTargetId, ...items: unknown[]): void {
|
|
const message = formatMessage(items);
|
|
originalConsole.error(message);
|
|
void sendFrontendLog("error", targetId, message).catch(caughtError => originalConsole.error("KSP frontend logging bridge failed", caughtError));
|
|
}
|
|
|
|
function buildConsoleBridge(level: FrontendLogLevel, targetId: FrontendLogTargetId, original: ConsoleMethod): ConsoleMethod {
|
|
return (...items: unknown[]) => {
|
|
original(...items);
|
|
void sendFrontendLog(level, targetId, formatMessage(items)).catch(caughtError => originalConsole.error("KSP frontend logging bridge failed", caughtError));
|
|
};
|
|
}
|
|
|
|
export function installFrontendConsoleBridge(targetId: FrontendLogTargetId): void {
|
|
console.trace = buildConsoleBridge("trace", targetId, originalConsole.trace);
|
|
console.debug = buildConsoleBridge("debug", targetId, originalConsole.debug);
|
|
console.log = buildConsoleBridge("info", targetId, originalConsole.log);
|
|
console.info = buildConsoleBridge("info", targetId, originalConsole.info);
|
|
console.warn = buildConsoleBridge("warn", targetId, originalConsole.warn);
|
|
console.error = buildConsoleBridge("error", targetId, originalConsole.error);
|
|
}
|