// SonicForge App Logger — ghi hành động quan trọng của client (console + POST // /api/v1/logs để server log). Fire-and-forget: không throw, không block UI. // Các category dùng chung: // INSTRUMENT — lỗi load instrument (soundfont select/load fail) // VSTI — VSTi load/autosample/preview fail // MIDI_ITEM — MIDI item qua mastering fx chain / main out (playback) // DRAG_MIDI — lỗi drag MIDI từ MEDIA EXPLORER hoặc window explorer window.SonicAppLogger = window.SonicAppLogger || (function () { function base() { return window.API_BASE_URL || window.location.origin || ''; } function emit(category, level, message, data) { try { var line = '[AppLog][' + category + '][' + level + '] ' + message; if (data !== undefined && data !== null) { try { line += ' ' + JSON.stringify(data); } catch (e) {} } if (level === 'error') console.error(line); else if (level === 'warn') console.warn(line); else console.log(line); try { fetch(base() + '/api/v1/logs', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ category: category, level: level, message: message, data: data !== undefined ? data : null, url: window.location ? window.location.href : '', ts: new Date().toISOString() }) }).catch(function () {}); } catch (e) {} } catch (e) {} } return { info: function (category, message, data) { emit(category, 'info', message, data); }, warn: function (category, message, data) { emit(category, 'warn', message, data); }, error: function (category, message, data) { emit(category, 'error', message, data); } }; })();