Source: json-stream.js

/**
 * A class to decode JSON streams.
 */
class JSONStream {
  /** @type {Function} */
  #cb
  /** @type {number} */
  #obj
  /** @type {boolean} */
  #str
  /** @type {boolean} */
  #esc
  /** @type {string} */
  #data

  /**
   * Creates an instance of JSONStream.
   * @param {Function} cb - Callback function to handle parsed JSON objects.
   */
  constructor (cb) {
    this.#cb = cb
    this.#obj = 0
    this.#str = false
    this.#esc = false
  }

  /**
   * Decodes a string containing JSON data.
   * @param {string} str - The string to decode.
   */
  decode (str) {
    for (const char of str) {
      this.decodeChar(char)
    }
  }

  /**
   * Decodes a single character in the JSON string.
   * @param {string} c - The character to decode.
   */
  decodeChar (c) {
    // Start catching new object
    if (!this.#str && c === '{' && this.#obj++ === 0) {
      this.#data = ''
    }

    // Add character
    this.#data += c

    // Hide brackets in strings
    if (c === '"' && !this.#esc) {
      this.#str = !this.#str
    }

    // Track escape chars
    if (!this.#esc && c === '\\') {
      this.#esc = true
    } else if (this.#esc) {
      this.#esc = false
    }

    // Stop at closing bracket
    if (!this.#str && c === '}' && --this.#obj === 0) {
      this.#cb(JSON.parse(this.#data))
    }
  }
}

module.exports = JSONStream