From 0b0dda6cc2d91214604bf92702adb96e0333c9dd Mon Sep 17 00:00:00 2001 From: SukkaW Date: Sun, 17 Mar 2024 16:21:29 +0800 Subject: [PATCH] Chore: enable TextLineStream with env --- Build/build-deprecate-files.ts | 5 --- Build/lib/fetch-text-by-line.ts | 69 +++++++++++++++++++++------------ package.json | 1 + 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/Build/build-deprecate-files.ts b/Build/build-deprecate-files.ts index af975b56..5a6dd3af 100644 --- a/Build/build-deprecate-files.ts +++ b/Build/build-deprecate-files.ts @@ -18,11 +18,6 @@ export const buildDeprecateFiles = task(import.meta.path, (span) => span.traceCh const surgeFile = path.resolve(outputSurgeDir, `${filePath}.conf`); const clashFile = path.resolve(outputClashDir, `${filePath}.txt`); - console.log({ - surgeFile, - clashFile - }); - const content = [ '#########################################', '# Sukka\'s Ruleset - Deprecated', diff --git a/Build/lib/fetch-text-by-line.ts b/Build/lib/fetch-text-by-line.ts index 59b5814e..3c2cfd7c 100644 --- a/Build/lib/fetch-text-by-line.ts +++ b/Build/lib/fetch-text-by-line.ts @@ -1,20 +1,21 @@ import type { BunFile } from 'bun'; import { fetchWithRetry, defaultRequestInit } from './fetch-retry'; -// import { TextLineStream } from './text-line-transform-stream'; -// import { PolyfillTextDecoderStream } from './text-decoder-stream'; +import { TextLineStream } from './text-line-transform-stream'; +import { PolyfillTextDecoderStream } from './text-decoder-stream'; import { processLine } from './process-line'; -// function createTextLineStreamFromStreamSource(stream: ReadableStream) { -// return stream -// .pipeThrough(new PolyfillTextDecoderStream()) -// .pipeThrough(new TextLineStream()); -// } + +const enableTextLineStream = !!process.env.ENABLE_TEXT_LINE_STREAM; + +interface TextLineStreamLike { + [Symbol.asyncIterator](): AsyncIterableIterator +} const decoder = new TextDecoder('utf-8'); async function *createTextLineAsyncGeneratorFromStreamSource(stream: ReadableStream): AsyncGenerator { let buf = ''; - for await (const chunk of stream) { + for await (const chunk of stream as any) { const chunkStr = decoder.decode(chunk).replaceAll('\r\n', '\n'); for (let i = 0, len = chunkStr.length; i < len; i++) { const char = chunkStr[i]; @@ -32,25 +33,45 @@ async function *createTextLineAsyncGeneratorFromStreamSource(stream: ReadableStr } } -export function readFileByLine(file: string | URL | BunFile) { - if (typeof file === 'string') { - file = Bun.file(file); - } else if (!('writer' in file)) { - file = Bun.file(file); - } +export const readFileByLine: ((file: string | URL | BunFile) => TextLineStreamLike) = enableTextLineStream + ? (file: string | URL | BunFile) => { + if (typeof file === 'string') { + file = Bun.file(file); + } else if (!('writer' in file)) { + file = Bun.file(file); + } - return createTextLineAsyncGeneratorFromStreamSource(file.stream()); -} + return file.stream().pipeThrough(new PolyfillTextDecoderStream()).pipeThrough(new TextLineStream()); + } + : (file: string | URL | BunFile) => { + if (typeof file === 'string') { + file = Bun.file(file); + } else if (!('writer' in file)) { + file = Bun.file(file); + } -export function createReadlineInterfaceFromResponse(this: void, resp: Response) { - if (!resp.body) { - throw new Error('Failed to fetch remote text'); + return createTextLineAsyncGeneratorFromStreamSource(file.stream()) as any; + }; + +export const createReadlineInterfaceFromResponse: ((resp: Response) => TextLineStreamLike) = enableTextLineStream + ? (resp) => { + if (!resp.body) { + throw new Error('Failed to fetch remote text'); + } + if (resp.bodyUsed) { + throw new Error('Body has already been consumed.'); + } + return resp.body.pipeThrough(new PolyfillTextDecoderStream()).pipeThrough(new TextLineStream()); } - if (resp.bodyUsed) { - throw new Error('Body has already been consumed.'); - } - return createTextLineAsyncGeneratorFromStreamSource(resp.body); -} + : (resp) => { + if (!resp.body) { + throw new Error('Failed to fetch remote text'); + } + if (resp.bodyUsed) { + throw new Error('Body has already been consumed.'); + } + return createTextLineAsyncGeneratorFromStreamSource(resp.body) as any; + }; export function fetchRemoteTextByLine(url: string | URL) { return fetchWithRetry(url, defaultRequestInit).then(createReadlineInterfaceFromResponse); diff --git a/package.json b/package.json index 14c4a844..261e9e1c 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ }, "scripts": { "build": "bun ./Build/index.ts", + "build-stream": "ENABLE_TEXT_LINE_STREAM=true bun ./Build/index.ts", "lint": "eslint --format=sukka ." }, "author": "",