/** * TextBuffer Module * Manages text processing and sentence detection for the UI */ import { BaseModule } from './base-module.js'; import { moduleRegistry } from './module-registry.js'; class TextBufferModule extends BaseModule { constructor() { super('text-buffer', 'Text Buffer'); this.buffer = ''; this.sentenceEndRegex = /[.!?]\s+/g; // Detect sentence endings this.onSentenceReadyCallback = null; // Callback for complete sentences this.processingLock = false; // Lock to prevent concurrent processing } /** * Initialize the module * @returns {Promise} - Resolves with success status */ async initialize() { try { this.reportProgress(100, "Text buffer ready"); return true; } catch (error) { console.error("Error initializing Text Buffer:", error); return false; } } /** * Set callback function for when a sentence is ready * @param {Function} callback - Function to call with the sentence and completion callback */ setOnSentenceReady(callback) { if (typeof callback === 'function') { this.onSentenceReadyCallback = callback; console.log("Text Buffer: Sentence ready callback set"); } else { console.warn("Text Buffer: Invalid sentence ready callback provided"); } } /** * Add text to the buffer and process sentences * @param {string} text - Text to add to the buffer */ addText(text) { if (!text) return; console.log(`TextBuffer: Adding text: "${text.substring(0, 50)}${text.length > 50 ? '...' : ''}"`); // Add text to buffer this.buffer += text; // If we have a trailing newline as a complete sentence, add a period if (this.buffer.endsWith('\n') && !this.buffer.endsWith('.\n')) { const lastChar = this.buffer.charAt(this.buffer.length - 2); if (lastChar !== '.' && lastChar !== '!' && lastChar !== '?') { this.buffer = this.buffer.slice(0, -1) + '.\n'; } } // Process any complete sentences this.processSentences(); } /** * Process complete sentences in the buffer */ processSentences() { // Prevent concurrent processing if (this.processingLock) return; this.processingLock = true; try { // Check for sentence endings (including newlines as sentence endings) const sentenceEndings = [/[.!?]\s+/g, /[.!?]$/m, /\n/g]; let foundSentence = false; for (const pattern of sentenceEndings) { if (this.buffer.match(pattern)) { foundSentence = true; break; } } if (!foundSentence) { // No complete sentences yet this.processingLock = false; return; } // Process each complete sentence this.processNextSentence(); } catch (error) { console.error("Error processing sentences:", error); this.processingLock = false; } } /** * Process the next sentence in the buffer */ processNextSentence() { // Check for different sentence endings const patterns = [/[.!?]\s+/, /[.!?]$/, /\n/]; let match = null; let endIndex = -1; // Try to find the first sentence ending for (const pattern of patterns) { match = this.buffer.match(pattern); if (match) { endIndex = match.index + match[0].length; break; } } if (endIndex === -1) { // No complete sentence found this.processingLock = false; return; } const sentence = this.buffer.substring(0, endIndex); // Remove the processed sentence from buffer this.buffer = this.buffer.substring(endIndex); console.log(`TextBuffer: Processing sentence: "${sentence.trim()}"`); // Call the callback if set if (this.onSentenceReadyCallback) { this.onSentenceReadyCallback(sentence, () => { // After processing is complete, check for more sentences setTimeout(() => { if (this.buffer.length > 0) { this.processSentences(); } else { this.processingLock = false; } }, 0); }); } else { // No callback set, just process the next sentence if (this.buffer.length > 0) { this.processSentences(); } else { this.processingLock = false; } } } /** * Clear the text buffer */ clear() { this.buffer = ''; } /** * Get the current buffer content * @returns {string} - Current buffer content */ getBuffer() { return this.buffer; } } // Create the singleton instance const TextBuffer = new TextBufferModule(); // Register with the module registry moduleRegistry.register(TextBuffer); // Export the module export { TextBuffer }; // Keep a reference in window for loader system window.TextBuffer = TextBuffer;