{"version":3,"file":"newline-async-iterator.min.cjs","sources":["../../src/decodeUTF8.ts","../../src/compat.ts","../../src/index.ts"],"sourcesContent":["import { uint8ArrayToArray } from './compat.ts';\n\n/**\n * Get the expected length of a UTF-8 sequence from its first byte\n */\nfunction getUTF8SequenceLength(byte: number): number {\n  if (byte < 0x80) return 1; // 0xxxxxxx - ASCII\n  if (byte < 0xc0) return 0; // 10xxxxxx - continuation byte (invalid as start)\n  if (byte < 0xe0) return 2; // 110xxxxx\n  if (byte < 0xf0) return 3; // 1110xxxx\n  if (byte < 0xf8) return 4; // 11110xxx\n  return 0; // Invalid UTF-8 start byte\n}\n\n/**\n * Decode a single UTF-8 code point from bytes\n */\nfunction decodeCodePoint(bytes: number[], start: number, length: number): string {\n  let codePoint: number;\n\n  switch (length) {\n    case 1:\n      codePoint = bytes[start];\n      break;\n    case 2:\n      codePoint = ((bytes[start] & 0x1f) << 6) | (bytes[start + 1] & 0x3f);\n      break;\n    case 3:\n      codePoint = ((bytes[start] & 0x0f) << 12) | ((bytes[start + 1] & 0x3f) << 6) | (bytes[start + 2] & 0x3f);\n      break;\n    case 4:\n      codePoint = ((bytes[start] & 0x07) << 18) | ((bytes[start + 1] & 0x3f) << 12) | ((bytes[start + 2] & 0x3f) << 6) | (bytes[start + 3] & 0x3f);\n      break;\n    default:\n      return '\\ufffd'; // Replacement character for invalid sequences\n  }\n\n  // Handle code points outside BMP (need surrogate pairs in JavaScript)\n  if (codePoint > 0xffff) {\n    // Convert to surrogate pair\n    codePoint -= 0x10000;\n    return String.fromCharCode(0xd800 + (codePoint >> 10), 0xdc00 + (codePoint & 0x3ff));\n  }\n\n  return String.fromCharCode(codePoint);\n}\n\n/**\n * Create a fallback UTF-8 streaming decoder with its own state\n */\nfunction createFallbackDecoder(): (uint8Array: Uint8Array) => string {\n  let pendingBytes: number[] = [];\n\n  return function decode(uint8Array: Uint8Array): string {\n    // Combine pending bytes with new input\n    const inputBytes = uint8ArrayToArray(uint8Array);\n    const bytes = pendingBytes.length > 0 ? pendingBytes.concat(inputBytes) : inputBytes;\n    pendingBytes = [];\n\n    let result = '';\n    let i = 0;\n\n    while (i < bytes.length) {\n      const byte = bytes[i];\n      const sequenceLength = getUTF8SequenceLength(byte);\n\n      if (sequenceLength === 0) {\n        // Invalid start byte or continuation byte - emit replacement character\n        result += '\\ufffd';\n        i++;\n        continue;\n      }\n\n      if (i + sequenceLength > bytes.length) {\n        // Incomplete sequence - save for next chunk\n        pendingBytes = bytes.slice(i);\n        break;\n      }\n\n      result += decodeCodePoint(bytes, i, sequenceLength);\n      i += sequenceLength;\n    }\n\n    return result;\n  };\n}\n\n/**\n * Create a TextDecoder-based streaming decoder\n */\nfunction createTextDecoderDecoder(): (uint8Array: Uint8Array) => string {\n  const decoder = new TextDecoder('utf8');\n  return function decode(uint8Array: Uint8Array): string {\n    return decoder.decode(uint8Array, { stream: true });\n  };\n}\n\n/**\n * Create a new UTF-8 streaming decoder instance.\n * Each decoder maintains its own state for handling multi-byte\n * characters that span chunk boundaries.\n */\nexport default function createUTF8Decoder(): (uint8Array: Uint8Array) => string {\n  if (typeof TextDecoder !== 'undefined') {\n    return createTextDecoderDecoder();\n  }\n  return createFallbackDecoder();\n}\n","// Feature detection - no global modifications per polyfill-removal plans\n\n/**\n * Convert a Uint8Array to a number array\n * Compatible with Node 0.8+ (no Array.from)\n */\nexport function uint8ArrayToArray(uint8Array: Uint8Array): number[] {\n  if (typeof Array.from === 'function') return Array.from(uint8Array);\n\n  // Fallback for old environments without Array.from\n  const arr: number[] = [];\n  for (let i = 0; i < uint8Array.length; i++) {\n    arr.push(uint8Array[i]);\n  }\n  return arr;\n}\n","import createUTF8Decoder from './decodeUTF8.ts';\n\nconst REGEX_NEW_LINE = /\\r?\\n|\\r/g;\n\nconst root = typeof window === 'undefined' ? global : window;\n// biome-ignore lint/suspicious/noShadowRestrictedNames: Legacy\nconst Symbol: SymbolConstructor = typeof root.Symbol === 'undefined' ? ({ asyncIterator: undefined } as unknown as SymbolConstructor) : root.Symbol;\n\n/**\n * Create a newline iterator recognizing CR, LF, and CRLF using the Symbol.asyncIterator interface\n *\n * @param source The async iterable of Uint8Array chunks to iterate through\n *\n * ```typescript\n * import newlineIterator from \"newline-async-iterator\";\n *\n * const iterator = newlineIterator(readableStream);\n * const results = [];\n * for await (const line of iterator) results.push(line);\n * console.log(results); // [\"some\", \"string\", \"combination\"];\n * ```\n */\n\nexport default function newlineIterator(source: AsyncIterable<Uint8Array> | AsyncIterator<Uint8Array>): AsyncIterableIterator<string> {\n  const decodeUTF8 = createUTF8Decoder();\n  const lines = [];\n  let last = '';\n  let done = false;\n\n  const sourceIterator = Symbol.asyncIterator ? source[Symbol.asyncIterator]() : source;\n\n  function generateNext(): Promise<IteratorResult<string, boolean>> {\n    return new Promise((resolve, reject) => {\n      sourceIterator.next().then((next) => {\n        if (next.done) done = true;\n        else last += decodeUTF8(next.value);\n\n        const end = last.length > 0 ? last[last.length - 1] : '';\n        if (done || (end !== '\\r' && end !== '\\n')) {\n          const moreLines = last.split(REGEX_NEW_LINE);\n          last = moreLines.pop();\n          moreLines.forEach((line) => {\n            lines.unshift(line);\n          });\n          if (done && last.length > 0) {\n            lines.unshift(last);\n            last = '';\n          }\n        }\n\n        if (lines.length > 0) {\n          const value = lines.pop();\n          if (done && lines.length === 0 && value.length === 0) return resolve({ value: null, done: true });\n          return resolve({ value, done: false });\n        }\n        if (done) return resolve({ value: null, done: true });\n        generateNext().then(resolve).catch(reject); // get more\n      });\n    });\n  }\n\n  const iterator = {\n    next(): Promise<IteratorResult<string, boolean>> {\n      return generateNext();\n    },\n    [Symbol.asyncIterator](): AsyncIterator<string> {\n      return this;\n    },\n  };\n\n  return iterator as AsyncIterableIterator<string>;\n}\n"],"names":["getUTF8SequenceLength","byte","decodeCodePoint","bytes","start","length","codePoint","String","fromCharCode","createFallbackDecoder","pendingBytes","uint8Array","inputBytes","Array","from","arr","i","push","uint8ArrayToArray","concat","result","sequenceLength","slice","createUTF8Decoder","TextDecoder","decoder","decode","stream","REGEX_NEW_LINE","root","window","global","Symbol","asyncIterator","undefined","source","decodeUTF8","lines","last","done","sourceIterator","generateNext","Promise","resolve","reject","next","then","value","end","moreLines","split","pop","forEach","line","unshift","catch","this"],"mappings":"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"}