feat: add live replays and PostgreSQL maintenance tools
Build and Push Docker Container / build-and-push (push) Successful in 7m53s
Build and Push Docker Container / build-and-push (push) Successful in 7m53s
- Stream compact live replay updates across local and clustered dashboards. - Render responsive snake bodies as SVG paths with aligned custom icons. - Add cache-busted assets, replay fallback routes, and live-follow playback. - Support PostgreSQL benchmark sampling and idempotent SQLite migration. - Add dry-run cleanup for old low-quality PostgreSQL replay payloads. - Reward safe perimeter lanes and bump Prism to version 1.5.0. - Add backend, migration, dashboard, and perimeter regression coverage.
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Snake Dashboard</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/root.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
||||
<link rel="stylesheet" href="{{ static_url('css/root.css') }}">
|
||||
<link rel="stylesheet" href="{{ static_url('css/styles.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
@@ -51,6 +51,7 @@
|
||||
<option value="400">1.5x</option>
|
||||
<option value="250">2x</option>
|
||||
<option value="160">2.5x</option>
|
||||
<option value="120">3x</option>
|
||||
</select>
|
||||
</label>
|
||||
<input type="range" min="0" max="0" step="1" id="turn-slider" value="0">
|
||||
@@ -68,16 +69,16 @@
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="{{ url_for('static', filename='js/Utils.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/Snake.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/MoveTable.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/SnakeTable.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/GameBoard.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/OverallStats.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/GamesTable.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/Thinking.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/DashboardWebSocket.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/GameState.js') }}"></script>
|
||||
<script src="{{ static_url('js/Utils.js') }}"></script>
|
||||
<script src="{{ static_url('js/Snake.js') }}"></script>
|
||||
<script src="{{ static_url('js/MoveTable.js') }}"></script>
|
||||
<script src="{{ static_url('js/SnakeTable.js') }}"></script>
|
||||
<script src="{{ static_url('js/GameBoard.js') }}"></script>
|
||||
<script src="{{ static_url('js/OverallStats.js') }}"></script>
|
||||
<script src="{{ static_url('js/GamesTable.js') }}"></script>
|
||||
<script src="{{ static_url('js/Thinking.js') }}"></script>
|
||||
<script src="{{ static_url('js/DashboardWebSocket.js') }}"></script>
|
||||
<script src="{{ static_url('js/GameState.js') }}"></script>
|
||||
<script>
|
||||
const initialGameId = {{ initial_game_id|tojson }};
|
||||
const initialSummary = {{ initial_summary|tojson }};
|
||||
@@ -102,6 +103,20 @@
|
||||
gameState._gamesTable = gamesTable;
|
||||
|
||||
const dashboardWS = new DashboardWebSocket({
|
||||
onReplayUpdate: (payload) => {
|
||||
const games = Array.isArray(dashboardGamesPayload.games)
|
||||
? dashboardGamesPayload.games
|
||||
: [];
|
||||
const listedGame = games.find(
|
||||
(game) => String(game.game_id) === String(payload.game_id),
|
||||
);
|
||||
if (listedGame && payload.game) {
|
||||
listedGame.final_turn = payload.game.final_turn;
|
||||
listedGame.status = payload.game.status;
|
||||
gamesTable.render(games, gameState.activeGameId);
|
||||
}
|
||||
gameState.applyLiveTurn(payload.game_id, payload.game, payload.turn);
|
||||
},
|
||||
onGamesUpdate: (payload) => {
|
||||
if (payload.summary) {
|
||||
dashboardSummary = payload.summary;
|
||||
@@ -111,6 +126,11 @@
|
||||
dashboardGamesPayload = payload.games;
|
||||
const games = Array.isArray(dashboardGamesPayload.games) ? dashboardGamesPayload.games : [];
|
||||
gamesTable.render(games, gameState.activeGameId);
|
||||
const activeGame = games.find((game) => String(game.game_id) === gameState.activeGameId);
|
||||
if (activeGame && gameState.replay && gameState.replay.game) {
|
||||
gameState.replay.game.status = activeGame.status;
|
||||
gameState.replay.game.final_turn = activeGame.final_turn;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user