All files / src/utils line-buffer.ts

100% Statements 61/61
100% Branches 15/15
100% Functions 5/5
100% Lines 61/61

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 621x 1x 1x 1x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 30x 1x 1x 29x 29x 29x 29x 29x 2x 2x 29x 27x 5x 5x 5x 5x 27x 27x 27x 26x 26x 26x 27x 29x 30x 34x 34x 31x 1x 1x 30x 31x 5x 5x 5x 30x 30x 30x 34x 34x 23x 23x 34x  
import EventEmitter from 'node:events'
 
import { nlRegexp } from './regexp'
 
export default class LineBuffer extends EventEmitter {
  lines: string[]
  #closed: boolean
  #partialLine: string
 
  constructor() {
    super()
 
    this.lines = []
    this.#closed = false
    this.#partialLine = ''
  }
 
  append(data: string): void {
    if (this.#closed) {
      throw new Error('LineBuffer is closed')
    }
 
    if (data.length) {
      let appendLines = data.split(nlRegexp)
 
      if (appendLines.length === 1) {
        let [appendLine] = appendLines
        this.#partialLine = `${this.#partialLine}${appendLine}`
      } else {
        if (this.#partialLine) {
          let appendLine = `${this.#partialLine}${appendLines.shift()}`
          this.emit('line', appendLine)
          this.lines.push(appendLine)
        }
 
        this.#partialLine = appendLines.pop() as string
        for (let appendLine of appendLines) {
          this.emit('line', appendLine)
          this.lines.push(appendLine)
        }
      }
    }
  }
 
  close(): void {
    if (this.#closed) {
      throw new Error('LineBuffer is closed')
    }
 
    if (this.#partialLine) {
      this.emit('line', this.#partialLine)
      this.lines.push(this.#partialLine)
    }
 
    this.#closed = true
  }
 
  toString(): string {
    return this.lines.join('\n')
  }
}