MCPcopy
hub / github.com/codeaashu/claude-code / readLinesReverse

Function readLinesReverse

src/utils/fsOperations.ts:722–770  ·  view source on GitHub ↗
(
  path: string,
)

Source from the content-addressed store, hash-verified

720 * @returns An async generator that yields lines in reverse order
721 */
722export async function* readLinesReverse(
723 path: string,
724): AsyncGenerator<string, void, undefined> {
725 const CHUNK_SIZE = 1024 * 4
726 const fileHandle = await open(path, 'r')
727 try {
728 const stats = await fileHandle.stat()
729 let position = stats.size
730 // Carry raw bytes (not a decoded string) across chunk boundaries so that
731 // multi-byte UTF-8 sequences split by the 4KB boundary are not corrupted.
732 // Decoding per-chunk would turn a split sequence into U+FFFD on both sides,
733 // which for history.jsonl means JSON.parse throws and the entry is dropped.
734 let remainder = Buffer.alloc(0)
735 const buffer = Buffer.alloc(CHUNK_SIZE)
736
737 while (position > 0) {
738 const currentChunkSize = Math.min(CHUNK_SIZE, position)
739 position -= currentChunkSize
740
741 await fileHandle.read(buffer, 0, currentChunkSize, position)
742 const combined = Buffer.concat([
743 buffer.subarray(0, currentChunkSize),
744 remainder,
745 ])
746
747 const firstNewline = combined.indexOf(0x0a)
748 if (firstNewline === -1) {
749 remainder = combined
750 continue
751 }
752
753 remainder = Buffer.from(combined.subarray(0, firstNewline))
754 const lines = combined.toString('utf8', firstNewline + 1).split('\n')
755
756 for (let i = lines.length - 1; i >= 0; i--) {
757 const line = lines[i]!
758 if (line) {
759 yield line
760 }
761 }
762 }
763
764 if (remainder.length > 0) {
765 yield remainder.toString('utf8')
766 }
767 } finally {
768 await fileHandle.close()
769 }
770}
771

Callers 1

makeLogEntryReaderFunction · 0.85

Calls 4

openFunction · 0.85
readMethod · 0.65
toStringMethod · 0.65
closeMethod · 0.45

Tested by

no test coverage detected