* Fix H1: Process stream data with proper line buffering * Handles incomplete lines that span multiple data chunks and * multi-byte UTF-8 characters that might be split across chunks
(data: Buffer, stream: 'stdout' | 'stderr')
| 757 | * multi-byte UTF-8 characters that might be split across chunks |
| 758 | */ |
| 759 | private processStreamData(data: Buffer, stream: 'stdout' | 'stderr'): void { |
| 760 | // Use StringDecoder to properly handle multi-byte UTF-8 characters |
| 761 | const decoder = stream === 'stdout' ? this.stdoutDecoder : this.stderrDecoder; |
| 762 | const bufferKey = stream === 'stdout' ? 'stdoutBuffer' : 'stderrBuffer'; |
| 763 | |
| 764 | // Decode buffer (handles partial UTF-8 sequences correctly) |
| 765 | const decoded = decoder.write(data); |
| 766 | |
| 767 | // Combine with any incomplete line from previous chunk |
| 768 | const content = this[bufferKey] + decoded; |
| 769 | const lines = content.split('\n'); |
| 770 | |
| 771 | this.lastActivity = new Date(); |
| 772 | |
| 773 | // The last element might be incomplete - save for next chunk |
| 774 | this[bufferKey] = lines.pop() || ''; |
| 775 | |
| 776 | // Process complete lines |
| 777 | for (const line of lines) { |
| 778 | const trimmedLine = line.trim(); |
| 779 | if (!trimmedLine) continue; |
| 780 | |
| 781 | this.simpleLogManager.appendLog(trimmedLine, stream).catch(() => {}); |
| 782 | |
| 783 | const logLine: LogLine = { |
| 784 | content: trimmedLine, |
| 785 | timestamp: new Date(), |
| 786 | stream, |
| 787 | processId: this.processInfo.id |
| 788 | }; |
| 789 | // CircularBuffer automatically handles capacity - O(1) push |
| 790 | this.logBuffer.push(logLine); |
| 791 | |
| 792 | this.parseJsonLog(trimmedLine); |
| 793 | } |
| 794 | } |
| 795 | |
| 796 | private parseJsonLog(line: string): void { |
| 797 | try { |
no test coverage detected