feat: асинхронное обновление списков в LuCI (fix XHR timeout) и форматированный config.json

- backend: добавлены команды list_update_async и list_update_status с отслеживанием шагов в /var/run/tachyon/list-update.status
- ui: кнопка ручного обновления списков теперь запускает операцию в фоне, показывает модалку с индикатором и опрашивает статус (устранен таймаут LuCI XHR в 30 сек)
- json: sing-box config.json теперь форматируется с отступами в 2 пробела (sprintf '%.2J') для удобства чтения
- tests: обновлены тесты и добавлены проверки для list-update-status (122/122 passed)
This commit is contained in:
Dushnilin
2026-09-06 17:55:40 +03:00
parent 2fd8c2dca3
commit 625715fed0
10 changed files with 256 additions and 17 deletions
+3 -2
View File
@@ -67,11 +67,12 @@ function csv_to_json_array(value) {
// rename. Both failure paths already report to the caller through `false`, and
// an unlink that throws means the temp file was never created — nothing left
// to clean up.
function write_json_file(path, value) {
function write_json_file(path, value, indent) {
path = as_string(path);
let stamp = clock();
let tmp_path = sprintf("%s.%d.%d.tmp", path, stamp[0], stamp[1]);
let result = fs.writefile(tmp_path, sprintf("%J\n", value));
let fmt = (indent != null && indent > 0) ? sprintf("%%.%dJ\n", indent) : "%J\n";
let result = fs.writefile(tmp_path, sprintf(fmt, value));
if (result == null || (type(result) == "boolean" && !result)) {
try { fs.unlink(tmp_path); } catch(e) {}
return false;