@@ -3,6 +3,7 @@ import * as fs from 'fs'
33import * as path from 'path'
44import * as git from 'isomorphic-git'
55import { LRUCache } from 'lru-cache'
6+ import { isBinaryPath , detectBinaryByContent , SNIFF_BYTES } from '../shared/binary'
67
78type Msg =
89 | { id : number ; type : 'loadRepo' ; repoPath : string }
@@ -17,19 +18,6 @@ const blobCache = new LRUCache<string, { binary: boolean; text: string | null }>
1718let blobCacheHits = 0
1819const gitCache : Record < string , any > = Object . create ( null )
1920const WORKDIR = '__WORKDIR__'
20- const BINARY_EXTS = [
21- '.png' , '.jpg' , '.jpeg' , '.gif' , '.bmp' , '.webp' , '.ico' ,
22- '.pdf' , '.zip' , '.rar' , '.7z' , '.tar' , '.gz' , '.tgz' ,
23- '.mp3' , '.wav' , '.flac' ,
24- '.mp4' , '.mov' , '.avi' , '.mkv' , '.webm' ,
25- '.exe' , '.dll' , '.bin' , '.dmg' , '.pkg' , '.iso' ,
26- '.woff' , '.woff2' , '.ttf' , '.otf' ,
27- '.svg'
28- ]
29- function isBinaryPathLocal ( p : string ) : boolean {
30- const lower = p . toLowerCase ( )
31- return BINARY_EXTS . some ( ext => lower . endsWith ( ext ) )
32- }
3321
3422// Helper function to parse packed-refs
3523async function parsePackedRefs ( repoPath : string ) : Promise < string [ ] > {
@@ -58,14 +46,7 @@ function ok(id: number, data?: any) { send({ id, type: 'ok', data }) }
5846function err ( id : number , error : string ) { send ( { id, type : 'error' , error } ) }
5947function progress ( id : number , message : string ) { send ( { id, type : 'progress' , message } ) }
6048
61- function looksBinary ( buf : Buffer ) : boolean {
62- const len = Math . min ( buf . length , 8000 )
63- for ( let i = 0 ; i < len ; i ++ ) {
64- const c = buf [ i ]
65- if ( c === 0 ) return true
66- }
67- return false
68- }
49+ // (content sniffing comes from shared helper)
6950
7051parentPort ?. on ( 'message' , async ( m : Msg ) => {
7152 try {
@@ -141,7 +122,7 @@ parentPort?.on('message', async (m: Msg) => {
141122 }
142123 case 'readFile' : {
143124 // Fast path: known-binary extension => no content read
144- if ( isBinaryPathLocal ( m . filepath ) ) {
125+ if ( isBinaryPath ( m . filepath ) ) {
145126 if ( m . ref !== WORKDIR ) {
146127 ok ( m . id , { binary : true , text : null , notFound : false } ) ; return
147128 }
@@ -168,17 +149,32 @@ parentPort?.on('message', async (m: Msg) => {
168149 const res = await git . readBlob ( { fs, dir : repoPath , oid : commitOid , filepath : m . filepath } ) . catch ( ( ) => null )
169150 if ( ! res ) { ok ( m . id , { binary : false , text : null , notFound : true } ) ; return }
170151 const buf = Buffer . from ( res . blob )
171- const binary = looksBinary ( buf )
152+ const sample = buf . subarray ( 0 , SNIFF_BYTES )
153+ const binary = detectBinaryByContent ( sample , m . filepath )
172154 const value = { binary, text : binary ? null : buf . toString ( 'utf8' ) }
173155 blobCache . set ( cacheKey , value )
174156 ok ( m . id , { ...value , notFound : false } )
175157 return
176158 }
159+ // Partial read to sniff type without pulling whole large files
177160 const fileAbs = path . join ( repoPath , m . filepath )
178- const buf = await fs . promises . readFile ( fileAbs ) . catch ( ( ) => null as any )
179- if ( ! buf ) { ok ( m . id , { binary : false , text : null , notFound : true } ) ; return }
180- const binary = looksBinary ( buf as Buffer )
181- ok ( m . id , { binary, text : binary ? null : ( buf as Buffer ) . toString ( 'utf8' ) } )
161+ const fd = await fs . promises . open ( fileAbs , 'r' ) . catch ( ( ) => null as any )
162+ if ( ! fd ) { ok ( m . id , { binary : false , text : null , notFound : true } ) ; return }
163+ try {
164+ const probe = Buffer . allocUnsafe ( SNIFF_BYTES )
165+ const { bytesRead } = await fd . read ( probe , 0 , SNIFF_BYTES , 0 )
166+ const sample = probe . subarray ( 0 , bytesRead )
167+ const binary = detectBinaryByContent ( sample , m . filepath )
168+ if ( binary ) {
169+ ok ( m . id , { binary : true , text : null , notFound : false } )
170+ } else {
171+ // Now read full text if needed
172+ const full = await fs . promises . readFile ( fileAbs , 'utf8' )
173+ ok ( m . id , { binary : false , text : full , notFound : false } )
174+ }
175+ } finally {
176+ await fd . close ( ) . catch ( ( ) => { } )
177+ }
182178 return
183179 }
184180 case 'listFiles' : {
0 commit comments