Replace polling with websocket live sync

This commit is contained in:
2026-04-02 02:31:59 +03:00
parent 9a3785deb9
commit c04847b21c
15 changed files with 596 additions and 28 deletions

View File

@@ -16,6 +16,7 @@ import {
} from './lib/config';
import { getDashboardSnapshot } from './lib/snapshot';
import { AuthService } from './lib/auth';
import type { LiveSyncPublisher } from './lib/liveSync';
import type { RuntimeController } from './lib/runtime';
import { StateStore } from './lib/store';
@@ -24,9 +25,10 @@ export interface AppServices {
runtime: RuntimeController;
runtimeRootDir: string;
auth: AuthService;
liveSync?: LiveSyncPublisher;
}
export function createApp({ store, runtime, runtimeRootDir, auth }: AppServices) {
export function createApp({ store, runtime, runtimeRootDir, auth, liveSync }: AppServices) {
const app = express();
const runtimePaths = buildRuntimePaths(runtimeRootDir);
const distDir = path.resolve('dist');
@@ -106,6 +108,7 @@ export function createApp({ store, runtime, runtimeRootDir, auth }: AppServices)
}
await writeConfigAndState(store, state, runtimePaths);
liveSync?.notifyPotentialChange();
response.json(await getDashboardSnapshot(store, runtime, runtimePaths));
} catch (error) {
next(error);
@@ -120,6 +123,7 @@ export function createApp({ store, runtime, runtimeRootDir, auth }: AppServices)
state.userRecords.push(record);
state.service.lastEvent = `User ${record.username} created from panel`;
await persistRuntimeMutation(store, runtime, state, runtimePaths);
liveSync?.notifyPotentialChange();
response.status(201).json(await getDashboardSnapshot(store, runtime, runtimePaths));
} catch (error) {
next(error);
@@ -147,6 +151,7 @@ export function createApp({ store, runtime, runtimeRootDir, auth }: AppServices)
? `System configuration updated from panel and removed ${removedUsers.length} linked users`
: 'System configuration updated from panel';
await persistRuntimeMutation(store, runtime, state, runtimePaths);
liveSync?.notifyPotentialChange();
response.json(await getDashboardSnapshot(store, runtime, runtimePaths));
} catch (error) {
next(error);
@@ -169,6 +174,7 @@ export function createApp({ store, runtime, runtimeRootDir, auth }: AppServices)
: `User ${user.username} resumed from panel`;
await persistRuntimeMutation(store, runtime, state, runtimePaths);
liveSync?.notifyPotentialChange();
response.json(await getDashboardSnapshot(store, runtime, runtimePaths));
} catch (error) {
next(error);
@@ -188,6 +194,7 @@ export function createApp({ store, runtime, runtimeRootDir, auth }: AppServices)
const [removed] = state.userRecords.splice(index, 1);
state.service.lastEvent = `User ${removed.username} deleted from panel`;
await persistRuntimeMutation(store, runtime, state, runtimePaths);
liveSync?.notifyPotentialChange();
response.json(await getDashboardSnapshot(store, runtime, runtimePaths));
} catch (error) {
next(error);