import { LogLevel, createCatalogDiagnostics, type DiagnosticCatalog, type DiagnosticEvent, type Diagnostics } from '$libs/logr'; import { CONN_DIAGNOSTIC_EVENTS, CONN_EVENT_MESSAGE, CONN_MODULE, CONN_LOG_MSG_AUTH_FAILED, CONN_LOG_MSG_BROWSER_RECONNECT, CONN_LOG_MSG_CONNECT_FAILED, CONN_LOG_MSG_FRAME_DECODE_FAILED, CONN_LOG_MSG_FRAME_ENCODE_FAILED, CONN_LOG_MSG_HEARTBEAT_TIMEOUT, CONN_LOG_MSG_REAUTH_FAILED, CONN_LOG_MSG_RECONNECT_EXHAUSTED, CONN_LOG_MSG_SEND_FAILED, CONN_LOG_MSG_SESSION_CHANGED, CONN_LOG_MSG_SESSION_EXPIRED, CONN_LOG_MSG_SESSION_REFRESHED, CONN_LOG_MSG_SESSION_REVOKED, CONN_LOG_MSG_TRANSPORT_ERROR } from './consts.ts'; import { listenerThrewMessage } from './helpers.ts'; import type { Logger } from '$libs/logr'; export type ConnectionDiagnosticType = (typeof CONN_DIAGNOSTIC_EVENTS)[keyof typeof CONN_DIAGNOSTIC_EVENTS]; export type ConnectionDiagnosticEvent = DiagnosticEvent; export type ConnectionDiagnostics = Diagnostics; const CONN_DIAGNOSTIC_LOGS: DiagnosticCatalog = { [CONN_DIAGNOSTIC_EVENTS.AUTH_FAILED]: { level: LogLevel.WARN, message: CONN_LOG_MSG_AUTH_FAILED }, [CONN_DIAGNOSTIC_EVENTS.BROWSER_RECONNECT]: { level: LogLevel.DEBUG, message: CONN_LOG_MSG_BROWSER_RECONNECT }, [CONN_DIAGNOSTIC_EVENTS.CONNECT_FAILED]: { level: LogLevel.ERROR, message: CONN_LOG_MSG_CONNECT_FAILED }, [CONN_DIAGNOSTIC_EVENTS.FRAME_DECODE_FAILED]: { level: LogLevel.ERROR, message: CONN_LOG_MSG_FRAME_DECODE_FAILED }, [CONN_DIAGNOSTIC_EVENTS.FRAME_ENCODE_FAILED]: { level: LogLevel.ERROR, message: CONN_LOG_MSG_FRAME_ENCODE_FAILED }, [CONN_DIAGNOSTIC_EVENTS.HEARTBEAT_TIMEOUT]: { level: LogLevel.WARN, message: CONN_LOG_MSG_HEARTBEAT_TIMEOUT }, [CONN_DIAGNOSTIC_EVENTS.LISTENER_THREW]: (event) => ({ level: LogLevel.ERROR, message: listenerThrewMessage(listenerEventName(event.meta)) }), [CONN_DIAGNOSTIC_EVENTS.REAUTH_FAILED]: { level: LogLevel.WARN, message: CONN_LOG_MSG_REAUTH_FAILED }, [CONN_DIAGNOSTIC_EVENTS.RECONNECT_EXHAUSTED]: { level: LogLevel.WARN, message: CONN_LOG_MSG_RECONNECT_EXHAUSTED }, [CONN_DIAGNOSTIC_EVENTS.SEND_FAILED]: { level: LogLevel.ERROR, message: CONN_LOG_MSG_SEND_FAILED }, [CONN_DIAGNOSTIC_EVENTS.SESS_CHANGED]: { level: LogLevel.DEBUG, message: CONN_LOG_MSG_SESSION_CHANGED }, [CONN_DIAGNOSTIC_EVENTS.SESS_EXPIRED]: { level: LogLevel.WARN, message: CONN_LOG_MSG_SESSION_EXPIRED }, [CONN_DIAGNOSTIC_EVENTS.SESS_REFRESHED]: { level: LogLevel.DEBUG, message: CONN_LOG_MSG_SESSION_REFRESHED }, [CONN_DIAGNOSTIC_EVENTS.SESS_REVOKED]: { level: LogLevel.WARN, message: CONN_LOG_MSG_SESSION_REVOKED }, [CONN_DIAGNOSTIC_EVENTS.TRANSPORT_ERROR]: { level: LogLevel.ERROR, message: CONN_LOG_MSG_TRANSPORT_ERROR } }; function listenerEventName(meta: unknown): string { if (typeof meta !== 'object' || meta === null) return CONN_EVENT_MESSAGE; if (!('event' in meta)) return CONN_EVENT_MESSAGE; const event = meta.event; return typeof event === 'string' && event.length > 0 ? event : CONN_EVENT_MESSAGE; } export function createConnectionDiagnostics(input: { readonly logger?: Logger; readonly scope: string; }): ConnectionDiagnostics { return createCatalogDiagnostics({ logger: input.logger, defaultCategory: input.scope, catalog: CONN_DIAGNOSTIC_LOGS }); } export function emitConnectionDiagnostic( diagnostics: ConnectionDiagnostics, type: ConnectionDiagnosticType, meta?: unknown ): void { diagnostics.emit({ artifact: CONN_MODULE, type, meta }); } export function emitScopedConnectionDiagnostic( diagnostics: ConnectionDiagnostics, scope: string, type: ConnectionDiagnosticType, meta?: unknown ): void { diagnostics.emit({ artifact: CONN_MODULE, scope, type, meta }); }