65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
import type { ProxyUserRecord } from '../../src/shared/contracts';
|
|
import { deriveDashboardSnapshot, render3proxyConfig, type ObservedRuntimeState, type RuntimePaths, type RuntimeSnapshot } from './config';
|
|
import type { StateStore } from './store';
|
|
import { readObservedTraffic } from './traffic';
|
|
|
|
export async function getDashboardSnapshot(
|
|
store: StateStore,
|
|
runtime: { getSnapshot(): RuntimeSnapshot },
|
|
runtimePaths: RuntimePaths,
|
|
) {
|
|
const state = await store.read();
|
|
const previewConfig = render3proxyConfig(state, runtimePaths);
|
|
const traffic = await readObservedTraffic(runtimePaths, state.userRecords);
|
|
const observedUsers = deriveObservedUsers(state.userRecords, traffic.userBytesByName, traffic.recentUsers);
|
|
const observed: ObservedRuntimeState = {
|
|
totalBytes: traffic.totalBytes,
|
|
liveConnections: traffic.liveConnections,
|
|
activeUsers: traffic.activeUsers,
|
|
daily: traffic.daily,
|
|
userRecords: observedUsers,
|
|
};
|
|
|
|
return deriveDashboardSnapshot(state, runtime.getSnapshot(), observed, previewConfig);
|
|
}
|
|
|
|
function deriveObservedUsers(
|
|
users: ProxyUserRecord[],
|
|
userBytesByName: Map<string, number>,
|
|
recentUsers: Set<string>,
|
|
): ProxyUserRecord[] {
|
|
return users.map((user) => {
|
|
const usedBytes = userBytesByName.get(user.username) ?? 0;
|
|
|
|
if (user.paused) {
|
|
return {
|
|
...user,
|
|
usedBytes,
|
|
status: 'idle',
|
|
};
|
|
}
|
|
|
|
if (user.quotaBytes !== null && usedBytes >= user.quotaBytes) {
|
|
return {
|
|
...user,
|
|
usedBytes,
|
|
status: 'fail',
|
|
};
|
|
}
|
|
|
|
if (user.quotaBytes !== null && user.quotaBytes > 0 && usedBytes / user.quotaBytes >= 0.8) {
|
|
return {
|
|
...user,
|
|
usedBytes,
|
|
status: recentUsers.has(user.username) ? 'live' : 'warn',
|
|
};
|
|
}
|
|
|
|
return {
|
|
...user,
|
|
usedBytes,
|
|
status: recentUsers.has(user.username) ? 'live' : 'idle',
|
|
};
|
|
});
|
|
}
|