|
|
|
|
|
|
|
|
|
|
|
import { Logger } from './logger.js'; |
|
|
|
|
|
export class AppState { |
|
|
constructor() { |
|
|
|
|
|
this.currentSessionId = null; |
|
|
this.isSolving = false; |
|
|
this.currentIteration = 0; |
|
|
this.maxIterationsCount = 8; |
|
|
this.isAwaitingUserFeedback = false; |
|
|
|
|
|
|
|
|
this.currentSessionData = null; |
|
|
this.selectedSessionId = null; |
|
|
this.sessionsExpanded = false; |
|
|
|
|
|
|
|
|
this.streamingMessages = new Map(); |
|
|
this.executionSpinners = new Map(); |
|
|
|
|
|
|
|
|
this.solvingTimeoutId = null; |
|
|
this.connectionTimeoutId = null; |
|
|
this.lastHeartbeat = Date.now(); |
|
|
this.connectionRetries = 0; |
|
|
|
|
|
|
|
|
this.SOLVING_TIMEOUT_MS = 300000; |
|
|
this.CONNECTION_TIMEOUT_MS = 30000; |
|
|
this.HEARTBEAT_INTERVAL_MS = 15000; |
|
|
this.MAX_CONNECTION_RETRIES = 3; |
|
|
|
|
|
|
|
|
this.SESSION_STORAGE_KEY = 'pips_sessions'; |
|
|
|
|
|
|
|
|
|
|
|
this.listeners = {}; |
|
|
} |
|
|
|
|
|
|
|
|
on(event, callback) { |
|
|
if (!this.listeners[event]) { |
|
|
this.listeners[event] = []; |
|
|
} |
|
|
this.listeners[event].push(callback); |
|
|
} |
|
|
|
|
|
emit(event, data) { |
|
|
if (this.listeners[event]) { |
|
|
this.listeners[event].forEach(callback => callback(data)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
setCurrentSession(sessionData) { |
|
|
this.currentSessionData = sessionData; |
|
|
this.emit('sessionChanged', sessionData?.id); |
|
|
Logger.debug('State', 'Current session updated', sessionData?.id); |
|
|
} |
|
|
|
|
|
setSelectedSession(sessionId) { |
|
|
this.selectedSessionId = sessionId; |
|
|
this.emit('selectedSessionChanged', sessionId); |
|
|
Logger.debug('State', 'Selected session changed', sessionId); |
|
|
} |
|
|
|
|
|
|
|
|
setSolving(solving) { |
|
|
this.isSolving = solving; |
|
|
this.emit('solvingStateChanged', solving); |
|
|
Logger.debug('State', `Solving state: ${solving}`); |
|
|
} |
|
|
|
|
|
setIteration(iteration) { |
|
|
this.currentIteration = iteration; |
|
|
this.emit('iterationChanged', iteration); |
|
|
} |
|
|
|
|
|
|
|
|
setUserFeedback(awaiting) { |
|
|
this.isAwaitingUserFeedback = awaiting; |
|
|
this.emit('userFeedbackStateChanged', awaiting); |
|
|
Logger.debug('State', `User feedback state: ${awaiting}`); |
|
|
} |
|
|
|
|
|
|
|
|
setConnectionRetries(retries) { |
|
|
this.connectionRetries = retries; |
|
|
this.emit('connectionRetriesChanged', retries); |
|
|
} |
|
|
|
|
|
updateLastHeartbeat() { |
|
|
this.lastHeartbeat = Date.now(); |
|
|
} |
|
|
|
|
|
|
|
|
setSolvingTimeout(timeoutId) { |
|
|
this.clearSolvingTimeout(); |
|
|
this.solvingTimeoutId = timeoutId; |
|
|
} |
|
|
|
|
|
clearSolvingTimeout() { |
|
|
if (this.solvingTimeoutId) { |
|
|
clearTimeout(this.solvingTimeoutId); |
|
|
this.solvingTimeoutId = null; |
|
|
} |
|
|
} |
|
|
|
|
|
setConnectionTimeout(timeoutId) { |
|
|
this.clearConnectionTimeout(); |
|
|
this.connectionTimeoutId = timeoutId; |
|
|
} |
|
|
|
|
|
clearConnectionTimeout() { |
|
|
if (this.connectionTimeoutId) { |
|
|
clearTimeout(this.connectionTimeoutId); |
|
|
this.connectionTimeoutId = null; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
addStreamingMessage(id, element) { |
|
|
this.streamingMessages.set(id, element); |
|
|
} |
|
|
|
|
|
removeStreamingMessage(id) { |
|
|
this.streamingMessages.delete(id); |
|
|
} |
|
|
|
|
|
addExecutionSpinner(id, element) { |
|
|
this.executionSpinners.set(id, element); |
|
|
} |
|
|
|
|
|
removeExecutionSpinner(id) { |
|
|
this.executionSpinners.delete(id); |
|
|
} |
|
|
|
|
|
|
|
|
getSnapshot() { |
|
|
return { |
|
|
currentSessionId: this.currentSessionId, |
|
|
isSolving: this.isSolving, |
|
|
currentIteration: this.currentIteration, |
|
|
selectedSessionId: this.selectedSessionId, |
|
|
connectionRetries: this.connectionRetries, |
|
|
lastHeartbeat: this.lastHeartbeat, |
|
|
streamingMessagesCount: this.streamingMessages.size, |
|
|
executionSpinnersCount: this.executionSpinners.size |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
reset() { |
|
|
this.currentSessionId = null; |
|
|
this.isSolving = false; |
|
|
this.currentIteration = 0; |
|
|
this.isAwaitingUserFeedback = false; |
|
|
this.currentSessionData = null; |
|
|
this.selectedSessionId = null; |
|
|
this.clearSolvingTimeout(); |
|
|
this.clearConnectionTimeout(); |
|
|
this.streamingMessages.clear(); |
|
|
this.executionSpinners.clear(); |
|
|
this.emit('stateReset'); |
|
|
Logger.debug('State', 'Application state reset'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
export const appState = new AppState(); |