@sap-ai-sdk/core
Version:
**This package is designed for internal usage and should not be consumed directly.**
80 lines • 2.73 kB
JavaScript
/**
* A re-implementation of httpx's `LineDecoder` in Python that handles incrementally
* reading lines from text.
*
* Https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258.
*/
export class LineDecoder {
// prettier-ignore
static NEWLINE_CHARS = new Set(['\n', '\r']);
static NEWLINE_REGEXP = /\r\n|[\n\r]/g;
buffer;
trailingCR;
textDecoder; // TextDecoder found in browsers; not typed to avoid pulling in either "dom" or "node" types.
constructor() {
this.buffer = [];
this.trailingCR = false;
}
decode(chunk) {
let text = this.decodeText(chunk);
if (this.trailingCR) {
text = '\r' + text;
this.trailingCR = false;
}
if (text.endsWith('\r')) {
this.trailingCR = true;
text = text.slice(0, -1);
}
if (!text) {
return [];
}
const trailingNewline = LineDecoder.NEWLINE_CHARS.has(text[text.length - 1] || '');
let lines = text.split(LineDecoder.NEWLINE_REGEXP);
// if there is a trailing new line then the last entry will be an empty
// string which we don't care about
if (trailingNewline) {
lines.pop();
}
if (lines.length === 1 && !trailingNewline) {
this.buffer.push(lines[0]);
return [];
}
if (this.buffer.length) {
lines = [this.buffer.join('') + lines[0], ...lines.slice(1)];
this.buffer = [];
}
if (!trailingNewline) {
this.buffer = [lines.pop() || ''];
}
return lines;
}
decodeText(bytes) {
if (bytes == null) {
return '';
}
if (typeof bytes === 'string') {
return bytes;
}
// Node:
if (typeof Buffer !== 'undefined') {
if (bytes instanceof Buffer) {
return bytes.toString();
}
if (bytes instanceof Uint8Array) {
return Buffer.from(bytes).toString();
}
throw new Error(`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.`);
}
throw new Error('Unexpected: Buffer is not available as globals. Please report this error.');
}
flush() {
if (!this.buffer.length && !this.trailingCR) {
return [];
}
const lines = [this.buffer.join('')];
this.buffer = [];
this.trailingCR = false;
return lines;
}
}
//# sourceMappingURL=line-decoder.js.map