Multi-Hoster-Upload/lib/config-store.js
Administrator 7d992206e8 feat: byse.sx health check + performance optimizations for large queues
- Add byse.sx health check via API upload/server endpoint
- Virtual scrolling for queue table (>200 rows renders only visible rows)
- O(1) job lookups via index Maps instead of O(n) array.find()
- Event delegation on queue tbody instead of per-row listeners
- Async config writes to avoid blocking main process
- Increase persist debounce to 3s during uploads (was 250ms)
- Reduce debug logging to state changes only
- Move save button to bottom-right in settings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 00:45:09 +01:00

115 lines
3.4 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const HOSTER_SETTINGS_DEFAULTS = {
retries: 3,
maxSpeedKbs: 0, // 0 = unlimited
parallelCount: 2, // 1-10
restartBelowKbs: 0, // 0 = off
timeIntervalSec: 0, // delay between jobs
maxSizeMb: 0 // 0 = unlimited
};
const DEFAULTS = {
hosters: {
'doodstream.com': { enabled: true, apiKey: '' },
'voe.sx': { enabled: true, apiKey: '' },
'vidmoly.me': { enabled: true, authType: 'login', username: '', password: '' },
'byse.sx': { enabled: true, apiKey: '' }
},
hosterSettings: {
'doodstream.com': { ...HOSTER_SETTINGS_DEFAULTS },
'voe.sx': { ...HOSTER_SETTINGS_DEFAULTS },
'vidmoly.me': { ...HOSTER_SETTINGS_DEFAULTS },
'byse.sx': { ...HOSTER_SETTINGS_DEFAULTS }
},
globalSettings: {
alwaysOnTop: false,
shutdownAfterFinish: 'nothing', // nothing | sleep | shutdown | restart
logFilePath: '',
resumeQueueOnLaunch: true,
pendingQueue: null,
scramble: {
active: false,
prefix: '',
suffix: '',
chars: 'both', // 'letters' | 'numbers' | 'both'
length: 0 // 0 = same as original basename length
}
},
history: []
};
const MAX_HISTORY = 100;
class ConfigStore {
constructor(app) {
const dir = app && app.isPackaged
? app.getPath('userData')
: path.join(__dirname, '..');
this.filePath = path.join(dir, 'electron-config.json');
}
load() {
try {
const raw = fs.readFileSync(this.filePath, 'utf-8');
const data = JSON.parse(raw);
// Merge with defaults so new hosters are always present
const hosters = { ...DEFAULTS.hosters };
for (const [name, val] of Object.entries(data.hosters || {})) {
if (hosters[name]) {
hosters[name] = { ...hosters[name], ...val };
}
}
// Merge hoster settings with defaults
const hosterSettings = {};
for (const name of Object.keys(DEFAULTS.hosterSettings)) {
hosterSettings[name] = {
...HOSTER_SETTINGS_DEFAULTS,
...(data.hosterSettings && data.hosterSettings[name] || {})
};
}
const globalSettings = {
...DEFAULTS.globalSettings,
...(data.globalSettings || {})
};
return { hosters, hosterSettings, globalSettings, history: data.history || [] };
} catch {
return JSON.parse(JSON.stringify(DEFAULTS));
}
}
save(config) {
const current = this.load();
if (config.hosters) current.hosters = config.hosters;
if (config.hosterSettings) current.hosterSettings = config.hosterSettings;
if (config.globalSettings) current.globalSettings = config.globalSettings;
// Async write to avoid blocking main process
const data = JSON.stringify(current, null, 2);
fs.writeFile(this.filePath, data, 'utf-8', () => {});
}
loadHistory() {
const config = this.load();
return config.history || [];
}
appendHistory(entry) {
const config = this.load();
config.history.push(entry);
// Cap at MAX_HISTORY
if (config.history.length > MAX_HISTORY) {
config.history = config.history.slice(-MAX_HISTORY);
}
fs.writeFileSync(this.filePath, JSON.stringify(config, null, 2), 'utf-8');
}
clearHistory() {
const config = this.load();
config.history = [];
fs.writeFileSync(this.filePath, JSON.stringify(config, null, 2), 'utf-8');
}
}
module.exports = ConfigStore;