diff --git a/apps/ccusage/src/data-loader.ts b/apps/ccusage/src/data-loader.ts index 8e22aae2..2ccf1c2c 100644 --- a/apps/ccusage/src/data-loader.ts +++ b/apps/ccusage/src/data-loader.ts @@ -535,7 +535,7 @@ export function createUniqueHash(data: UsageData): string | null { * @param filePath - Path to the JSONL file * @param processLine - Callback function to process each line */ -async function processJSONLFileByLine( +export async function processJSONLFileByLine( filePath: string, processLine: (line: string, lineNumber: number) => void | Promise, ): Promise { diff --git a/apps/ccusage/src/debug.ts b/apps/ccusage/src/debug.ts index 39af5e28..2ed0c629 100644 --- a/apps/ccusage/src/debug.ts +++ b/apps/ccusage/src/debug.ts @@ -7,7 +7,6 @@ * @module debug */ -import { readFile } from 'node:fs/promises'; import path from 'node:path'; import { Result } from '@praha/byethrow'; import { createFixture } from 'fs-fixture'; @@ -19,7 +18,7 @@ import { USAGE_DATA_GLOB_PATTERN, } from './_consts.ts'; import { PricingFetcher } from './_pricing-fetcher.ts'; -import { getClaudePaths, usageDataSchema } from './data-loader.ts'; +import { getClaudePaths, processJSONLFileByLine, usageDataSchema } from './data-loader.ts'; import { logger } from './logger.ts'; /** @@ -106,13 +105,8 @@ export async function detectMismatches(claudePath?: string): Promise line.length > 0); - - for (const line of lines) { + // Use streaming to avoid memory issues with large files + await processJSONLFileByLine(file, async (line) => { const parseParser = Result.try({ try: () => JSON.parse(line) as unknown, catch: () => new Error('Invalid JSON'), @@ -120,13 +114,13 @@ export async function detectMismatches(claudePath?: string): Promise