/**
 * Parses simple streaming JSON chunks of the format {"key": "content..."}
 * and yields only the content chunks, consuming the JSON structure.
 *
 * @param key - The JSON key to extract content from (e.g., "result", "text", "content")
 * @returns A function that takes a chunk and yields content chunks
 *
 * @example
 * ```ts
 * const parse = createJsonStreamParser("result");
 * for (const chunk of parse('{"result": "Hello')) {
 *   console.log(chunk); // Outputs: "Hello"
 * }
 * for (const chunk of parse(' world"}')) {
 *   console.log(chunk); // Outputs: " world"
 * }
 * ```
 */
export function createJsonStreamParser(key = "result") {
    let jsonBuffer = "";
    let isInsideValue = false;
    let isDone = false;
    let bufferedQuote = false;
    let isEscaped = false;
    const openingPattern = `{"${key}":`;
    return function* parseChunk(input) {
        // If we've already finished parsing, don't process more input
        if (isDone) {
            return;
        }
        let contentChunk = "";
        // If we buffered a quote from the last chunk, check if this chunk starts with }
        if (bufferedQuote) {
            bufferedQuote = false;
            // Only check for closing if the quote wasn't escaped
            if (!isEscaped && input[0] === "}") {
                // The buffered quote was indeed the closing quote
                isDone = true;
                if (contentChunk) {
                    yield contentChunk;
                }
                return;
            }
            else {
                // The buffered quote was part of the content
                contentChunk += '"';
                isEscaped = false; // Reset escape state after processing buffered quote
            }
        }
        for (let i = 0; i < input.length; i++) {
            const char = input[i];
            if (!isInsideValue) {
                jsonBuffer += char;
                // Check if we've consumed the opening {"key": "
                if (jsonBuffer.includes(openingPattern) &&
                    char === '"' &&
                    jsonBuffer.endsWith('"')) {
                    // Found the opening quote of the value
                    const colonIndex = jsonBuffer.lastIndexOf(":");
                    if (colonIndex !== -1 && jsonBuffer.slice(colonIndex).includes('"')) {
                        isInsideValue = true;
                        jsonBuffer = "";
                    }
                }
            }
            else {
                // We're inside the value
                // Handle escape sequences
                if (isEscaped) {
                    // Previous char was \, so this char is escaped - unescape it
                    switch (char) {
                        case '"':
                        case "\\":
                        case "/":
                            contentChunk += char;
                            break;
                        case "b":
                            contentChunk += "\b";
                            break;
                        case "f":
                            contentChunk += "\f";
                            break;
                        case "n":
                            contentChunk += "\n";
                            break;
                        case "r":
                            contentChunk += "\r";
                            break;
                        case "t":
                            contentChunk += "\t";
                            break;
                        default:
                            // For unknown escape sequences, preserve the backslash
                            contentChunk += "\\" + char;
                            break;
                    }
                    isEscaped = false;
                    continue;
                }
                if (char === "\\") {
                    // This is an escape character, mark next char as escaped
                    // Don't add it to content yet - wait to see what's being escaped
                    isEscaped = true;
                    continue;
                }
                // Check for closing quote (only if not escaped)
                if (char === '"') {
                    // Look ahead to see if this is followed by }
                    const nextChar = input[i + 1];
                    if (nextChar === "}") {
                        // This is the closing quote, stop parsing
                        isDone = true;
                        if (contentChunk) {
                            yield contentChunk;
                        }
                        return;
                    }
                    else if (nextChar === undefined) {
                        // We don't know yet if this is the closing quote
                        // Buffer it and wait for the next chunk
                        bufferedQuote = true;
                        break;
                    }
                    // If nextChar is something else, this quote is part of content
                }
                contentChunk += char;
            }
        }
        // Yield the accumulated content chunk (if we're not just buffering a quote)
        if (contentChunk && !bufferedQuote) {
            yield contentChunk;
        }
        else if (contentChunk && bufferedQuote) {
            // Yield everything except the buffered quote
            yield contentChunk;
        }
    };
}
//# sourceMappingURL=json-stream-parser.js.map