Compare commits

..

No commits in common. "73e7190913843720f3980172ce091e5c9a6de985" and "ae46d90dc2fff1b1b931e30aef57c306bd7f86c7" have entirely different histories.

4 changed files with 8 additions and 63 deletions

View File

@ -20,7 +20,6 @@ export default [
clearTimeout: 'readonly',
setInterval: 'readonly',
clearInterval: 'readonly',
setImmediate: 'readonly',
Buffer: 'readonly',
URL: 'readonly',
fetch: 'readonly',

35
main.js
View File

@ -35,36 +35,10 @@ function getDebugLogPath() {
return path.join(baseDir, 'upload-debug.log');
}
// Buffered async writer: debugLog is called hundreds of times per second during
// busy uploads (unhandledRejection traces, progress transitions, folder-monitor
// events). Sync appendFileSync per call blocked the main event loop. We now
// queue lines in memory and flush on a short interval / on process exit.
const _debugLogBuffer = [];
let _debugLogFlushTimer = null;
let _debugLogWriting = false;
function _flushDebugLog() {
if (_debugLogWriting || _debugLogBuffer.length === 0) return;
const chunk = _debugLogBuffer.join('');
_debugLogBuffer.length = 0;
_debugLogWriting = true;
fs.appendFile(getDebugLogPath(), chunk, 'utf-8', () => {
_debugLogWriting = false;
// If more lines arrived during the write, flush them next tick.
if (_debugLogBuffer.length) setImmediate(_flushDebugLog);
});
}
function debugLog(msg) {
try {
const ts = new Date().toISOString();
_debugLogBuffer.push(`[${ts}] ${msg}\n`);
if (!_debugLogFlushTimer) {
_debugLogFlushTimer = setTimeout(() => {
_debugLogFlushTimer = null;
_flushDebugLog();
}, 500);
}
fs.appendFileSync(getDebugLogPath(), `[${ts}] ${msg}\n`, 'utf-8');
} catch {}
}
@ -751,13 +725,6 @@ app.on('before-quit', () => {
destroyCaptureWindow();
} catch {}
destroyDropTargetWindow();
// Flush pending debug-log buffer synchronously so no lines are lost.
try {
if (_debugLogBuffer.length) {
fs.appendFileSync(getDebugLogPath(), _debugLogBuffer.join(''), 'utf-8');
_debugLogBuffer.length = 0;
}
} catch {}
});
// --- IPC Handlers ---

View File

@ -1,6 +1,6 @@
{
"name": "multi-hoster-uploader",
"version": "2.8.6",
"version": "2.8.5",
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
"main": "main.js",
"scripts": {

View File

@ -60,9 +60,6 @@ const selectedRecentIds = new Set();
// Maintained incrementally — avoids O(n) filter() scans every 250ms in the status bar.
let _sessionDoneCount = 0;
let _sessionErrorCount = 0;
// O(1) dedup for maybeAddSessionFile (was O(n) sessionFilesData.some).
// Huge with thousands of rows × thousands of incoming results.
const _sessionFileKeys = new Set();
// --- Init ---
async function init() {
@ -96,13 +93,9 @@ async function init() {
window.api.onUpdateAvailable(showUpdateBanner);
window.api.onUpdateProgress(handleUpdateProgress);
// Upload event listeners — debug log only on state transitions; the 'uploading'
// tick fires 4×/sec per active job and an IPC roundtrip per event would
// backlog the renderer↔main channel with hundreds of messages/sec.
// Upload event listeners — with debug logging to file
window.api.onUploadProgress((data) => {
if (data.status !== 'uploading') {
window.api.debugLog('RX upload-progress: ' + data.status + ' ' + data.hoster + ' ' + (data.fileName || ''));
}
window.api.debugLog('RX upload-progress: ' + data.status + ' ' + data.hoster + ' ' + (data.fileName || ''));
handleProgress(data);
});
window.api.onUploadBatchDone((data) => {
@ -110,10 +103,7 @@ async function init() {
handleBatchDone(data);
});
window.api.onUploadStats((data) => {
// Stats fire every second per upload session — skip while uploading.
if (data.state !== 'uploading') {
window.api.debugLog('RX upload-stats: state=' + data.state + ' active=' + data.activeJobs);
}
window.api.debugLog('RX upload-stats: state=' + data.state + ' active=' + data.activeJobs);
handleStats(data);
});
window.api.onShutdownCountdown(handleShutdownCountdown);
@ -1015,18 +1005,11 @@ function _renderVirtualRows(tbody) {
tbody.innerHTML = html;
}
// Coalesce rapid scroll events (a fast trackpad fling fires dozens) into one
// render per frame. rAF keeps the scroll thread cheap.
let _queueScrollQueued = false;
function _onQueueScroll() {
if (_queueScrollQueued) return;
if (_sortedJobsCache.length < 200) return;
_queueScrollQueued = true;
requestAnimationFrame(() => {
_queueScrollQueued = false;
if (_sortedJobsCache.length >= 200) {
const tbody = document.getElementById('queueBody');
if (tbody) _renderVirtualRows(tbody);
});
}
}
const _collatorDE = new Intl.Collator('de', { sensitivity: 'base', numeric: true });
@ -1196,7 +1179,6 @@ function deleteSelectedRecentFiles() {
sessionFilesData = sessionFilesData.filter(r => {
if (!selectedRecentIds.has(r.order)) return true;
if (r.isError) removedErr++; else removedDone++;
_sessionFileKeys.delete(`${r.link}\u0001${r.filename}\u0001${r.host}`);
return false;
});
_sessionDoneCount = Math.max(0, _sessionDoneCount - removedDone);
@ -1209,7 +1191,6 @@ function clearAllRecentFiles() {
if (sessionFilesData.length === 0) return;
if (!confirm(`Wirklich alle ${sessionFilesData.length} Links aus diesem Panel entfernen?`)) return;
sessionFilesData = [];
_sessionFileKeys.clear();
_sessionDoneCount = 0;
_sessionErrorCount = 0;
selectedRecentIds.clear();
@ -1968,9 +1949,7 @@ function maybeAddSessionFile(job) {
if (job.status === 'done' && job.result) {
const link = job.result.download_url || job.result.embed_url || '';
if (!link) return;
const dedupKey = `${link}\u0001${job.fileName}\u0001${job.hoster}`;
if (!_sessionFileKeys.has(dedupKey)) {
_sessionFileKeys.add(dedupKey);
if (!sessionFilesData.some((row) => row.link === link && row.filename === job.fileName && row.host === job.hoster)) {
sessionFilesData.push({
date: dt.text,
dateTs: dt.ts,