| 356 | } |
| 357 | |
| 358 | function readFileInRangeStreaming( |
| 359 | filePath: string, |
| 360 | offset: number, |
| 361 | maxLines: number | undefined, |
| 362 | maxBytes: number | undefined, |
| 363 | truncateOnByteLimit: boolean, |
| 364 | signal?: AbortSignal, |
| 365 | ): Promise<ReadFileRangeResult> { |
| 366 | return new Promise((resolve, reject) => { |
| 367 | const state: StreamState = { |
| 368 | stream: createReadStream(filePath, { |
| 369 | encoding: 'utf8', |
| 370 | highWaterMark: 512 * 1024, |
| 371 | ...(signal ? { signal } : undefined), |
| 372 | }), |
| 373 | offset, |
| 374 | endLine: maxLines !== undefined ? offset + maxLines : Infinity, |
| 375 | maxBytes, |
| 376 | truncateOnByteLimit, |
| 377 | resolve, |
| 378 | totalBytesRead: 0, |
| 379 | selectedBytes: 0, |
| 380 | truncatedByBytes: false, |
| 381 | currentLineIndex: 0, |
| 382 | selectedLines: [], |
| 383 | partial: '', |
| 384 | isFirstChunk: true, |
| 385 | resolveMtime: () => {}, |
| 386 | mtimeReady: null as unknown as Promise<number>, |
| 387 | } |
| 388 | state.mtimeReady = new Promise<number>(r => { |
| 389 | state.resolveMtime = r |
| 390 | }) |
| 391 | |
| 392 | state.stream.once('open', streamOnOpen.bind(state)) |
| 393 | state.stream.on('data', streamOnData.bind(state)) |
| 394 | state.stream.once('end', streamOnEnd.bind(state)) |
| 395 | state.stream.once('error', reject) |
| 396 | }) |
| 397 | } |