From f97605ff268f4bf7a8b90d6e4f994d455481a183 Mon Sep 17 00:00:00 2001 From: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> Date: Thu, 30 Jul 2026 03:37:50 +0530 Subject: [PATCH] refactor: use promise event APIs for git log processing Iterate the log parser with for-await instead of data/end/error callbacks (spawn errors are forwarded by destroying the stream), and await the single-file lookup with events.once, which rejects on child error by itself. Co-Authored-By: Claude Fable 5 --- src/node/utils/getGitTimestamp.ts | 56 +++++++++++++------------------ 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/src/node/utils/getGitTimestamp.ts b/src/node/utils/getGitTimestamp.ts index d5ac5ec9..a22db188 100644 --- a/src/node/utils/getGitTimestamp.ts +++ b/src/node/utils/getGitTimestamp.ts @@ -1,4 +1,5 @@ import { spawn, sync } from 'cross-spawn' +import { once } from 'node:events' import fs from 'node:fs' import path from 'node:path' import { Transform, type TransformCallback } from 'node:stream' @@ -120,23 +121,17 @@ export async function cacheAllGitTimestamps( ...pathspec ] - return new Promise((resolve, reject) => { - cache.clear() - const child = spawn('git', args, { cwd: root }) + cache.clear() + const child = spawn('git', args, { cwd: root }) + const records = child.stdout.pipe(new GitLogParser()) + child.on('error', (err) => records.destroy(err)) - child.stdout - .pipe(new GitLogParser()) - .on('data', (rec: GitLogRecord) => { - for (const file of rec.files) { - const slashed = slash(path.resolve(gitRoot, file)) - if (!cache.has(slashed)) cache.set(slashed, rec.ts) - } - }) - .on('error', reject) - .on('end', resolve) - - child.on('error', reject) - }) + for await (const rec of records as AsyncIterable) { + for (const file of rec.files) { + const slashed = slash(path.resolve(gitRoot, file)) + if (!cache.has(slashed)) cache.set(slashed, rec.ts) + } + } } export async function getGitTimestamp(file: string): Promise { @@ -148,24 +143,19 @@ export async function getGitTimestamp(file: string): Promise { if (!fs.existsSync(file)) return 0 - return new Promise((resolve, reject) => { - const child = spawn( - 'git', - ['log', '-1', '--pretty=%at', '--', path.basename(file)], - { cwd: path.dirname(file) } - ) - - let output = '' - child.stdout.on('data', (d) => (output += String(d))) + const child = spawn( + 'git', + ['log', '-1', '--pretty=%at', '--', path.basename(file)], + { cwd: path.dirname(file) } + ) - child.on('close', () => { - const ts = Number.parseInt(output.trim(), 10) * 1000 - if (!(ts > 0)) return resolve(0) + let output = '' + child.stdout.on('data', (d) => (output += String(d))) + await once(child, 'close') - cache.set(file, ts) - resolve(ts) - }) + const ts = Number.parseInt(output.trim(), 10) * 1000 + if (!(ts > 0)) return 0 - child.on('error', reject) - }) + cache.set(file, ts) + return ts }