123 lines
4.0 KiB
JavaScript
123 lines
4.0 KiB
JavaScript
(function (root) {
|
|
'use strict';
|
|
|
|
var DEBUG_LOG_KEY = 'debugLogs';
|
|
var DEBUG_LOG_LIMIT = 1200;
|
|
var debugLogsCache = [];
|
|
var earlyDebugLogs = [];
|
|
var debugLogsLoaded = false;
|
|
var debugSaveTimer = null;
|
|
|
|
function trimText(value, limit) {
|
|
value = String(value == null ? '' : value);
|
|
limit = Math.max(20, Number(limit || 500));
|
|
return value.length > limit ? value.slice(0, limit) + '…' : value;
|
|
}
|
|
|
|
function makePlainLogValue(value, depth) {
|
|
depth = Number(depth || 0);
|
|
|
|
if (value == null) return value;
|
|
if (typeof value === 'string') return trimText(value, 900);
|
|
if (typeof value === 'number' || typeof value === 'boolean') return value;
|
|
if (value instanceof Error) return { name: value.name, message: value.message, stack: trimText(value.stack, 1200) };
|
|
if (value instanceof URL) return value.href;
|
|
if (depth > 3) return '[max-depth]';
|
|
|
|
if (Array.isArray(value)) {
|
|
return value.slice(0, 40).map(function (item) {
|
|
return makePlainLogValue(item, depth + 1);
|
|
});
|
|
}
|
|
|
|
if (typeof value === 'object') {
|
|
var result = {};
|
|
Object.keys(value).slice(0, 60).forEach(function (key) {
|
|
result[key] = makePlainLogValue(value[key], depth + 1);
|
|
});
|
|
return result;
|
|
}
|
|
|
|
return trimText(String(value), 300);
|
|
}
|
|
|
|
function trimDebugLogs(logs) {
|
|
logs = Array.isArray(logs) ? logs : [];
|
|
return logs.length > DEBUG_LOG_LIMIT ? logs.slice(logs.length - DEBUG_LOG_LIMIT) : logs;
|
|
}
|
|
|
|
function scheduleDebugSave() {
|
|
if (!debugLogsLoaded || debugSaveTimer) return;
|
|
|
|
debugSaveTimer = root.setTimeout(function () {
|
|
debugSaveTimer = null;
|
|
try {
|
|
var payload = {};
|
|
payload[DEBUG_LOG_KEY] = trimDebugLogs(debugLogsCache);
|
|
chrome.storage.local.set(payload);
|
|
} catch (e) {
|
|
// Diagnostics must never break redirect logic.
|
|
}
|
|
}, 80);
|
|
}
|
|
|
|
function initializeDebugLogs() {
|
|
var defaults = {};
|
|
defaults[DEBUG_LOG_KEY] = [];
|
|
|
|
try {
|
|
chrome.storage.local.get(defaults, function (items) {
|
|
var stored = Array.isArray(items[DEBUG_LOG_KEY]) ? items[DEBUG_LOG_KEY] : [];
|
|
debugLogsCache = trimDebugLogs(stored.concat(earlyDebugLogs));
|
|
earlyDebugLogs = [];
|
|
debugLogsLoaded = true;
|
|
scheduleDebugSave();
|
|
});
|
|
} catch (e) {
|
|
debugLogsLoaded = true;
|
|
}
|
|
}
|
|
|
|
function appendDebugLog(level, event, data) {
|
|
try {
|
|
var entry = {
|
|
time: new Date().toISOString(),
|
|
level: level || 'info',
|
|
event: String(event || 'log'),
|
|
data: makePlainLogValue(data || {})
|
|
};
|
|
|
|
if (!debugLogsLoaded) {
|
|
earlyDebugLogs.push(entry);
|
|
earlyDebugLogs = trimDebugLogs(earlyDebugLogs);
|
|
return;
|
|
}
|
|
|
|
debugLogsCache.push(entry);
|
|
debugLogsCache = trimDebugLogs(debugLogsCache);
|
|
scheduleDebugSave();
|
|
} catch (e) {
|
|
// Logging must never break redirect logic.
|
|
}
|
|
}
|
|
|
|
function log() {
|
|
var args = Array.prototype.slice.call(arguments);
|
|
console.log.apply(console, ['[Auto Mirror Switcher]'].concat(args));
|
|
appendDebugLog('info', args[0] || 'log', { args: args.slice(1) });
|
|
}
|
|
|
|
function warn() {
|
|
var args = Array.prototype.slice.call(arguments);
|
|
console.warn.apply(console, ['[Auto Mirror Switcher]'].concat(args));
|
|
appendDebugLog('warn', args[0] || 'warn', { args: args.slice(1) });
|
|
}
|
|
|
|
root.AutoMirrorDiagnostics = {
|
|
initializeDebugLogs: initializeDebugLogs,
|
|
appendDebugLog: appendDebugLog,
|
|
log: log,
|
|
warn: warn
|
|
};
|
|
})(typeof globalThis !== 'undefined' ? globalThis : this);
|