Improve local rules persistence and dirty-state handling
All checks were successful
Build and Deploy Gateway / build-and-push (push) Successful in 20s
Build and Deploy Gateway / deploy (push) Successful in 7s

This commit is contained in:
2026-07-11 22:37:04 +03:00
parent 1304a22f1f
commit 387cc273e8
9 changed files with 256 additions and 38 deletions

View File

@@ -380,11 +380,14 @@ async function applySelectedServer(selectedTag, { persist = true } = {}) {
else restoreSingboxConfig(previousConfig);
throw error;
}
if (persist) {
if (persist || stateStore.read().routeRulesPendingRestart) {
updateStoredState((state) => ({
...state,
appliedTag: selectedTag,
appliedAt: new Date().toISOString(),
...(persist ? {
appliedTag: selectedTag,
appliedAt: new Date().toISOString(),
} : {}),
routeRulesPendingRestart: false,
}));
}
}
@@ -393,18 +396,26 @@ async function applyRouteRules(routeRules) {
const state = normalizeStoredState(stateStore.read());
const cached = readSubscriptionCache();
if (!state.selectedTag || !cached?.config) {
updateStoredState((current) => ({ ...current, routeRules }));
updateStoredState((current) => ({
...current,
routeRules,
routeRulesPendingRestart: true,
}));
return;
}
const previousConfig = fs.existsSync(settings.configPath)
? fs.readFileSync(settings.configPath, 'utf8')
: null;
const wasRunning = singboxRuntime.running;
const wasRunning = Boolean((await singboxRuntime.refresh()).running);
try {
writeSingboxConfig(buildActiveConfig(cached.config, state.selectedTag, routeRules));
if (wasRunning) await startSingbox();
updateStoredState((current) => ({ ...current, routeRules }));
updateStoredState((current) => ({
...current,
routeRules,
routeRulesPendingRestart: !wasRunning,
}));
} catch (error) {
if (previousConfig === null) removeSingboxConfig();
else restoreSingboxConfig(previousConfig);
@@ -656,6 +667,7 @@ async function handleApi(req, res) {
...state,
appliedTag: state.selectedTag,
connectionDesired: 'running',
routeRulesPendingRestart: false,
}));
}));
return sendState(res, { singboxRunning: true });
@@ -713,7 +725,13 @@ await refreshGatewayAutoMode({ reconfigure: false })
if (settings.appMode === 'client' || !fs.existsSync(settings.configPath)) {
writeCurrentConfig();
}
await startSingbox().catch((error) => console.warn(`[control] sing-box не запущен: ${error.message}`));
await startSingbox()
.then(() => {
if (fs.existsSync(settings.configPath) && stateStore.read().routeRulesPendingRestart) {
updateStoredState((state) => ({ ...state, routeRulesPendingRestart: false }));
}
})
.catch((error) => console.warn(`[control] sing-box не запущен: ${error.message}`));
server.listen(settings.port, '0.0.0.0', () => {
console.log(`[control] ${settings.appMode} UI слушает :${settings.port}`);