const MAX_LOG_ENTRIES = 300; const logBuffer = []; let snapshotProvider = null; let browserDiagnosticsInstalled = false; const safeError = (error) => { if (!error) return null; if (error instanceof Error) { return { name: error.name, message: error.message, stack: error.stack || null, }; } return { message: String(error) }; }; const trimLogs = () => { if (logBuffer.length > MAX_LOG_ENTRIES) { logBuffer.splice(0, logBuffer.length - MAX_LOG_ENTRIES); } }; export const airshipLog = (event, data = {}, level = 'info') => { const entry = { ts: new Date().toISOString(), level, event, ...data, }; logBuffer.push(entry); trimLogs(); const method = level === 'error' ? 'error' : level === 'warn' ? 'warn' : 'log'; console[method]('[airship]', event, entry); return entry; }; export const registerDebugSnapshot = (provider) => { snapshotProvider = typeof provider === 'function' ? provider : null; }; export const getAirshipLogs = () => logBuffer.map((entry) => ({ ...entry })); export const clearAirshipLogs = () => { logBuffer.length = 0; }; export const installBrowserDiagnostics = () => { if (typeof window === 'undefined' || browserDiagnosticsInstalled) return; browserDiagnosticsInstalled = true; window.__AIRSHIP_LOGS__ = logBuffer; window.airshipDebug = { getLogs: getAirshipLogs, clearLogs: clearAirshipLogs, snapshot: () => { try { return snapshotProvider?.() ?? null; } catch (error) { airshipLog('debug:snapshot-error', { error: safeError(error) }, 'error'); return null; } }, }; window.addEventListener('error', (event) => { airshipLog('runtime:error', { message: event.message || 'Unknown window error', source: event.filename || null, line: event.lineno || null, column: event.colno || null, error: safeError(event.error), }, 'error'); }); window.addEventListener('unhandledrejection', (event) => { airshipLog('runtime:unhandled-rejection', { error: safeError(event.reason), }, 'error'); }); airshipLog('diagnostics:installed', { userAgent: navigator?.userAgent || 'unknown', }); }; installBrowserDiagnostics();