Spaces:
Running
Running
| export interface ConsoleBufferMessage { | |
| id: string; | |
| type: "log" | "warn" | "error" | "info"; | |
| message: string; | |
| timestamp: number; | |
| context?: string; | |
| } | |
| export class ConsoleBuffer { | |
| private static instance: ConsoleBuffer | null = null; | |
| private messages: ConsoleBufferMessage[] = []; | |
| private maxMessages = 200; | |
| private lastReadTimestamp = 0; | |
| private executionContext: string | null = null; | |
| private messagesSinceLastTool: ConsoleBufferMessage[] = []; | |
| private constructor() {} | |
| static getInstance(): ConsoleBuffer { | |
| if (!ConsoleBuffer.instance) { | |
| ConsoleBuffer.instance = new ConsoleBuffer(); | |
| } | |
| return ConsoleBuffer.instance; | |
| } | |
| addMessage(message: ConsoleBufferMessage): void { | |
| if (this.executionContext) { | |
| message.context = this.executionContext; | |
| } | |
| this.messages.push(message); | |
| this.messagesSinceLastTool.push(message); | |
| if (this.messages.length > this.maxMessages) { | |
| this.messages = this.messages.slice(-this.maxMessages); | |
| } | |
| if (this.messagesSinceLastTool.length > 50) { | |
| this.messagesSinceLastTool = this.messagesSinceLastTool.slice(-50); | |
| } | |
| } | |
| getRecentMessages(since?: number, limit?: number): ConsoleBufferMessage[] { | |
| const sinceTimestamp = since || this.lastReadTimestamp; | |
| const filtered = this.messages.filter( | |
| (msg) => msg.timestamp > sinceTimestamp, | |
| ); | |
| if (limit && limit > 0 && filtered.length > limit) { | |
| return filtered.slice(-limit); | |
| } | |
| return filtered; | |
| } | |
| getAllMessages(limit?: number): ConsoleBufferMessage[] { | |
| if (limit && limit > 0 && this.messages.length > limit) { | |
| return this.messages.slice(-limit); | |
| } | |
| return [...this.messages]; | |
| } | |
| markAsRead(): void { | |
| if (this.messages.length > 0) { | |
| this.lastReadTimestamp = | |
| this.messages[this.messages.length - 1].timestamp; | |
| } | |
| } | |
| clear(): void { | |
| this.lastReadTimestamp = Date.now(); | |
| this.messagesSinceLastTool = []; | |
| } | |
| onGameReloadStart(): void { | |
| this.messagesSinceLastTool = []; | |
| this.lastReadTimestamp = Date.now(); | |
| this.addMessage({ | |
| id: `reload-${Date.now()}`, | |
| type: "info", | |
| message: "๐ Game reloading...", | |
| timestamp: Date.now(), | |
| }); | |
| } | |
| onGameReloadComplete(): void { | |
| this.addMessage({ | |
| id: `reload-complete-${Date.now()}`, | |
| type: "info", | |
| message: "โ Game reload complete", | |
| timestamp: Date.now(), | |
| }); | |
| } | |
| setExecutionContext(context: string | null): void { | |
| this.executionContext = context; | |
| } | |
| getMessagesSinceLastTool(): ConsoleBufferMessage[] { | |
| return [...this.messagesSinceLastTool]; | |
| } | |
| clearToolMessages(): void { | |
| this.messagesSinceLastTool = []; | |
| } | |
| getGameStateFromMessages(): { | |
| isLoading: boolean; | |
| hasError: boolean; | |
| lastError?: string; | |
| isReady: boolean; | |
| isReloading: boolean; | |
| messageCount: number; | |
| } { | |
| const recentMessages = | |
| this.messagesSinceLastTool.length > 0 | |
| ? this.messagesSinceLastTool | |
| : this.getRecentMessages(Date.now() - 5000); | |
| const hasReloadStartMessage = recentMessages.some((msg) => | |
| msg.message.includes("๐ Game reloading"), | |
| ); | |
| const hasReloadCompleteMessage = recentMessages.some((msg) => | |
| msg.message.includes("โ Game reload complete"), | |
| ); | |
| const hasStartMessage = recentMessages.some( | |
| (msg) => | |
| msg.message.includes("๐ฎ Starting game") || | |
| msg.message.includes("Starting game") || | |
| msg.message.includes("loading") || | |
| msg.message.includes("Loading"), | |
| ); | |
| const hasSuccessMessage = recentMessages.some( | |
| (msg) => | |
| msg.message.includes("โ Game started") || | |
| msg.message.includes("Game started!") || | |
| msg.message.includes("Game script loaded!") || | |
| msg.message.includes("โ Game reload complete") || | |
| msg.message.includes("successfully"), | |
| ); | |
| const errorMessages = recentMessages.filter( | |
| (msg) => | |
| msg.type === "error" || | |
| msg.message.includes("โ Error") || | |
| msg.message.includes("Error:") || | |
| msg.message.includes("Failed") || | |
| msg.message.includes("failed"), | |
| ); | |
| const lastError = | |
| errorMessages.length > 0 | |
| ? errorMessages[errorMessages.length - 1].message | |
| : undefined; | |
| const isReloading = hasReloadStartMessage && !hasReloadCompleteMessage; | |
| return { | |
| isLoading: | |
| (hasStartMessage || isReloading) && | |
| !hasSuccessMessage && | |
| errorMessages.length === 0, | |
| hasError: errorMessages.length > 0, | |
| lastError, | |
| isReady: hasSuccessMessage && errorMessages.length === 0 && !isReloading, | |
| isReloading, | |
| messageCount: recentMessages.length, | |
| }; | |
| } | |
| } | |
| export const consoleBuffer = ConsoleBuffer.getInstance(); | |