Track applied route rules separately from pending edits
All checks were successful
Build and Deploy Gateway / build-and-push (push) Successful in 16s
Build and Deploy Gateway / deploy (push) Successful in 7s

This commit is contained in:
2026-07-11 23:07:20 +03:00
parent 65bf88bf41
commit f135ade43b
9 changed files with 215 additions and 49 deletions

View File

@@ -20,7 +20,10 @@ export function normalizeStoredState(value) {
appliedTag: Object.hasOwn(state, 'appliedTag') ? text(state.appliedTag) : selectedTag,
servers: Array.isArray(state.servers) ? state.servers : [],
routeRules: normalizeRouteRules(state.routeRules),
routeRulesPendingRestart: state.routeRulesPendingRestart === true,
appliedRouteRules: normalizeRouteRules(state.appliedRouteRules),
routeRulesRevision: Number.isSafeInteger(state.routeRulesRevision) && state.routeRulesRevision >= 0
? state.routeRulesRevision
: 0,
};
}
@@ -57,6 +60,7 @@ export function createStateSnapshot({
};
});
const routeMode = mode === 'client' ? gatewayAuto?.mode || 'local-vpn' : 'gateway-transparent';
const activeLocalRules = runtime?.running ? stored.appliedRouteRules : [];
return assertStateSnapshot({
apiVersion: 1,
@@ -85,7 +89,9 @@ export function createStateSnapshot({
lastVerifiedAt: null,
reason: mode === 'client' && stored.gatewayAutoEnabled !== false ? 'auto' : 'manual',
localRules: stored.routeRules,
localRulesPendingRestart: stored.routeRulesPendingRestart,
activeLocalRules,
localRulesRevision: stored.routeRulesRevision,
localRulesPendingRestart: !isSameRules(stored.routeRules, activeLocalRules),
},
operation: {
kind: nullableText(operation.kind),
@@ -179,6 +185,10 @@ export function assertStateSnapshot(snapshot) {
typeof snapshot.route.reason !== 'string' ||
!Array.isArray(snapshot.route.localRules) ||
!snapshot.route.localRules.every(validRouteRule) ||
!Array.isArray(snapshot.route.activeLocalRules) ||
!snapshot.route.activeLocalRules.every(validRouteRule) ||
!Number.isSafeInteger(snapshot.route.localRulesRevision) ||
snapshot.route.localRulesRevision < 0 ||
typeof snapshot.route.localRulesPendingRestart !== 'boolean' ||
!snapshot.operation ||
!nullableString(snapshot.operation.kind) ||
@@ -193,3 +203,7 @@ export function assertStateSnapshot(snapshot) {
return snapshot;
}
function isSameRules(left, right) {
return JSON.stringify(left) === JSON.stringify(right);
}