mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-15 17:12:59 -04:00
83 lines
2.9 KiB
JavaScript
83 lines
2.9 KiB
JavaScript
// Replay Socket Hooks
|
|
// Purpose: Registers web socket replay-trigger handler that publishes replay requests.
|
|
// Scope: Applies replay mode/cooldown/source validation for socket-triggered replay requests.
|
|
const io = require('../../globals/io');
|
|
const logger = require('../../globals/logger').child('replaySocket');
|
|
const { getMode, MODES } = require('../modeManager');
|
|
const { publishEvent } = require('../eventBus');
|
|
const assignmentService = require('../assignmentService');
|
|
const { getNickname } = require('../nicknameService');
|
|
const { buildReplayJobId, buildReplayTitle } = require('../replayDeliveryService/workflow');
|
|
|
|
function buildRequesterLabel(socket) {
|
|
return getNickname(socket) || socket?.data?.user?.username || socket?.id || 'unknown';
|
|
}
|
|
|
|
function normalizeReplayTitle(value) {
|
|
if (typeof value !== 'string') return '';
|
|
return value.trim().slice(0, 120);
|
|
}
|
|
|
|
function normalizeIncludeSidebar(value) {
|
|
if (typeof value === 'boolean') return value;
|
|
return true;
|
|
}
|
|
|
|
function registerReplaySocketHooks({ tryTriggerReplay, validateSources, getDefaultWebSources }) {
|
|
io.on('connection', (socket) => {
|
|
const handleReplayTrigger = (payload = {}, cb = () => {}) => {
|
|
if (getMode() === MODES.LOCKDOWN) {
|
|
cb({ error: 'Replay disabled in lockdown', state: null });
|
|
return;
|
|
}
|
|
const requestedSources = Array.isArray(payload?.sources) ? payload.sources : null;
|
|
let sources = requestedSources ? validateSources(requestedSources, socket) : [];
|
|
if (!sources.length) {
|
|
const assignment = assignmentService.describeAssignment(socket.id);
|
|
sources = getDefaultWebSources(assignment, socket);
|
|
}
|
|
if (!sources.length) {
|
|
cb({ error: 'No replay sources selected', state: null });
|
|
return;
|
|
}
|
|
|
|
const requester = buildRequesterLabel(socket);
|
|
const title = normalizeReplayTitle(payload?.title);
|
|
const includeSidebar = normalizeIncludeSidebar(payload?.includeSidebar);
|
|
const jobId = buildReplayJobId('web');
|
|
const attempt = tryTriggerReplay({ by: { source: 'web', requester } });
|
|
if (!attempt.ok) {
|
|
cb({ error: 'Replay cooldown active', remainingMs: attempt.remainingMs, state: attempt.state });
|
|
return;
|
|
}
|
|
|
|
publishEvent({
|
|
source: 'replaySocket',
|
|
type: 'replay.requested',
|
|
payload: {
|
|
jobId,
|
|
requester,
|
|
title,
|
|
includeSidebar,
|
|
sources,
|
|
requestedBy: { socketId: socket.id },
|
|
},
|
|
});
|
|
logger.info('Replay requested via web', { socketId: socket.id, jobId });
|
|
cb({
|
|
success: true,
|
|
jobId,
|
|
status: 'accepted',
|
|
title: buildReplayTitle({ explicitTitle: title, sources }),
|
|
state: attempt.state,
|
|
});
|
|
};
|
|
|
|
socket.on('replay:trigger', handleReplayTrigger);
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
registerReplaySocketHooks,
|
|
};
|