line.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. "use strict";
  2. var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
  3. if (kind === "m") throw new TypeError("Private method is not writable");
  4. if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
  5. if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
  6. return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
  7. };
  8. var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
  9. if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
  10. if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
  11. return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
  12. };
  13. var _LineDecoder_carriageReturnIndex;
  14. Object.defineProperty(exports, "__esModule", { value: true });
  15. exports.findDoubleNewlineIndex = exports.LineDecoder = void 0;
  16. const error_1 = require("../../error.js");
  17. /**
  18. * A re-implementation of httpx's `LineDecoder` in Python that handles incrementally
  19. * reading lines from text.
  20. *
  21. * https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258
  22. */
  23. class LineDecoder {
  24. constructor() {
  25. _LineDecoder_carriageReturnIndex.set(this, void 0);
  26. this.buffer = new Uint8Array();
  27. __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f");
  28. }
  29. decode(chunk) {
  30. if (chunk == null) {
  31. return [];
  32. }
  33. const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk)
  34. : typeof chunk === 'string' ? new TextEncoder().encode(chunk)
  35. : chunk;
  36. let newData = new Uint8Array(this.buffer.length + binaryChunk.length);
  37. newData.set(this.buffer);
  38. newData.set(binaryChunk, this.buffer.length);
  39. this.buffer = newData;
  40. const lines = [];
  41. let patternIndex;
  42. while ((patternIndex = findNewlineIndex(this.buffer, __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f"))) != null) {
  43. if (patternIndex.carriage && __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") == null) {
  44. // skip until we either get a corresponding `\n`, a new `\r` or nothing
  45. __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, patternIndex.index, "f");
  46. continue;
  47. }
  48. // we got double \r or \rtext\n
  49. if (__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") != null &&
  50. (patternIndex.index !== __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") + 1 || patternIndex.carriage)) {
  51. lines.push(this.decodeText(this.buffer.slice(0, __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") - 1)));
  52. this.buffer = this.buffer.slice(__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f"));
  53. __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f");
  54. continue;
  55. }
  56. const endIndex = __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") !== null ? patternIndex.preceding - 1 : patternIndex.preceding;
  57. const line = this.decodeText(this.buffer.slice(0, endIndex));
  58. lines.push(line);
  59. this.buffer = this.buffer.slice(patternIndex.index);
  60. __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f");
  61. }
  62. return lines;
  63. }
  64. decodeText(bytes) {
  65. if (bytes == null)
  66. return '';
  67. if (typeof bytes === 'string')
  68. return bytes;
  69. // Node:
  70. if (typeof Buffer !== 'undefined') {
  71. if (bytes instanceof Buffer) {
  72. return bytes.toString();
  73. }
  74. if (bytes instanceof Uint8Array) {
  75. return Buffer.from(bytes).toString();
  76. }
  77. throw new error_1.OpenAIError(`Unexpected: received non-Uint8Array (${bytes.constructor.name}) stream chunk in an environment with a global "Buffer" defined, which this library assumes to be Node. Please report this error.`);
  78. }
  79. // Browser
  80. if (typeof TextDecoder !== 'undefined') {
  81. if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) {
  82. this.textDecoder ?? (this.textDecoder = new TextDecoder('utf8'));
  83. return this.textDecoder.decode(bytes);
  84. }
  85. throw new error_1.OpenAIError(`Unexpected: received non-Uint8Array/ArrayBuffer (${bytes.constructor.name}) in a web platform. Please report this error.`);
  86. }
  87. throw new error_1.OpenAIError(`Unexpected: neither Buffer nor TextDecoder are available as globals. Please report this error.`);
  88. }
  89. flush() {
  90. if (!this.buffer.length) {
  91. return [];
  92. }
  93. return this.decode('\n');
  94. }
  95. }
  96. exports.LineDecoder = LineDecoder;
  97. _LineDecoder_carriageReturnIndex = new WeakMap();
  98. // prettier-ignore
  99. LineDecoder.NEWLINE_CHARS = new Set(['\n', '\r']);
  100. LineDecoder.NEWLINE_REGEXP = /\r\n|[\n\r]/g;
  101. /**
  102. * This function searches the buffer for the end patterns, (\r or \n)
  103. * and returns an object with the index preceding the matched newline and the
  104. * index after the newline char. `null` is returned if no new line is found.
  105. *
  106. * ```ts
  107. * findNewLineIndex('abc\ndef') -> { preceding: 2, index: 3 }
  108. * ```
  109. */
  110. function findNewlineIndex(buffer, startIndex) {
  111. const newline = 0x0a; // \n
  112. const carriage = 0x0d; // \r
  113. for (let i = startIndex ?? 0; i < buffer.length; i++) {
  114. if (buffer[i] === newline) {
  115. return { preceding: i, index: i + 1, carriage: false };
  116. }
  117. if (buffer[i] === carriage) {
  118. return { preceding: i, index: i + 1, carriage: true };
  119. }
  120. }
  121. return null;
  122. }
  123. function findDoubleNewlineIndex(buffer) {
  124. // This function searches the buffer for the end patterns (\r\r, \n\n, \r\n\r\n)
  125. // and returns the index right after the first occurrence of any pattern,
  126. // or -1 if none of the patterns are found.
  127. const newline = 0x0a; // \n
  128. const carriage = 0x0d; // \r
  129. for (let i = 0; i < buffer.length - 1; i++) {
  130. if (buffer[i] === newline && buffer[i + 1] === newline) {
  131. // \n\n
  132. return i + 2;
  133. }
  134. if (buffer[i] === carriage && buffer[i + 1] === carriage) {
  135. // \r\r
  136. return i + 2;
  137. }
  138. if (buffer[i] === carriage &&
  139. buffer[i + 1] === newline &&
  140. i + 3 < buffer.length &&
  141. buffer[i + 2] === carriage &&
  142. buffer[i + 3] === newline) {
  143. // \r\n\r\n
  144. return i + 4;
  145. }
  146. }
  147. return -1;
  148. }
  149. exports.findDoubleNewlineIndex = findDoubleNewlineIndex;
  150. //# sourceMappingURL=line.js.map