diff --git a/Build/lib/fetch-assets.ts b/Build/lib/fetch-assets.ts index a2d8a4ce..b0261490 100644 --- a/Build/lib/fetch-assets.ts +++ b/Build/lib/fetch-assets.ts @@ -2,7 +2,7 @@ import picocolors from 'picocolors'; import { $$fetch, defaultRequestInit, ResponseError } from './fetch-retry'; import { waitWithAbort } from 'foxts/wait'; import { nullthrow } from 'foxts/guard'; -import { TextLineStream } from './text-line-transform-stream'; +import { TextLineStream } from 'foxts/text-line-stream'; import { ProcessLineStream } from './process-line'; // eslint-disable-next-line sukka/unicorn/custom-error-definition -- typescript is better @@ -32,7 +32,7 @@ export async function fetchAssets(url: string, fallbackUrls: null | undefined | } const res = await $$fetch(url, { signal: controller.signal, ...defaultRequestInit }); - let stream = nullthrow(res.body, url + ' has an empty body').pipeThrough(new TextDecoderStream()).pipeThrough(new TextLineStream()); + let stream = nullthrow(res.body, url + ' has an empty body').pipeThrough(new TextDecoderStream()).pipeThrough(new TextLineStream({ skipEmptyLines: processLine })); if (processLine) { stream = stream.pipeThrough(new ProcessLineStream()); } diff --git a/Build/lib/fetch-text-by-line.ts b/Build/lib/fetch-text-by-line.ts index 1e4c672b..9fc22bd0 100644 --- a/Build/lib/fetch-text-by-line.ts +++ b/Build/lib/fetch-text-by-line.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import readline from 'node:readline'; -import { TextLineStream } from './text-line-transform-stream'; +import { TextLineStream } from 'foxts/text-line-stream'; import type { ReadableStream } from 'node:stream/web'; import { TextDecoderStream } from 'node:stream/web'; import { processLine, ProcessLineStream } from './process-line'; @@ -31,7 +31,7 @@ export const createReadlineInterfaceFromResponse: ((resp: UndiciResponseData | U const resultStream = webStream .pipeThrough(new TextDecoderStream()) - .pipeThrough(new TextLineStream()); + .pipeThrough(new TextLineStream({ skipEmptyLines: processLine })); if (processLine) { return resultStream.pipeThrough(new ProcessLineStream()); diff --git a/Build/lib/text-line-transform-stream.ts b/Build/lib/text-line-transform-stream.ts deleted file mode 100644 index ac841afc..00000000 --- a/Build/lib/text-line-transform-stream.ts +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -// This module is browser compatible. -// Modified by Sukka (https://skk.moe) to increase compatibility and performance with Bun. - -import { TransformStream } from 'node:stream/web'; - -interface TextLineStreamOptions { - /** Allow splitting by solo \r */ - allowCR?: boolean -} - -/** Transform a stream into a stream where each chunk is divided by a newline, - * be it `\n` or `\r\n`. `\r` can be enabled via the `allowCR` option. - * - * ```ts - * const res = await fetch('https://example.com'); - * const lines = res.body! - * .pipeThrough(new TextDecoderStream()) - * .pipeThrough(new TextLineStream()); - * ``` - */ -export class TextLineStream extends TransformStream { - // private __buf = ''; - constructor({ - allowCR = false - }: TextLineStreamOptions = {}) { - let __buf = ''; - let chunkIndex = 0; - - super({ - transform(chunk, controller) { - chunk = __buf + chunk; - chunkIndex = 0; - - for (; ;) { - const lfIndex = chunk.indexOf('\n', chunkIndex); - - if (allowCR) { - const crIndex = chunk.indexOf('\r', chunkIndex); - - if ( - crIndex !== -1 && crIndex !== (chunk.length - 1) - && (lfIndex === -1 || (lfIndex - 1) > crIndex) - ) { - controller.enqueue(chunk.slice(chunkIndex, crIndex)); - chunkIndex = crIndex + 1; - continue; - } - } - - if (lfIndex === -1) { - // we can no longer find a line break in the chunk, break the current loop - break; - } - - // enqueue current line, and loop again to find next line - let crOrLfIndex = lfIndex; - if (chunk[lfIndex - 1] === '\r') { - crOrLfIndex--; - } - controller.enqueue(chunk.slice(chunkIndex, crOrLfIndex)); - chunkIndex = lfIndex + 1; - continue; - } - - __buf = chunk.slice(chunkIndex); - }, - flush(controller) { - if (__buf.length > 0) { - // eslint-disable-next-line sukka/string/prefer-string-starts-ends-with -- performance - if (allowCR && __buf[__buf.length - 1] === '\r') { - controller.enqueue(__buf.slice(0, -1)); - } else { - controller.enqueue(__buf); - } - } - } - }); - } -}