@@ -368,10 +368,12 @@ export class SyncEngine {
368368
369369 private async buildBinaryPayload ( file : TFile , vaultId : string ) : Promise < NotePayload > {
370370 // Attachments skip buildNotePayload (no markdown metadata) but still
371- // need hash + stat so the server can de-dupe and manifest diff works.
371+ // need raw bytes + hash + stat so the backend can ETL-extract text
372+ // and manifest diff still works.
372373 const buf = await this . deps . app . vault . readBinary ( file ) ;
373374 const digest = await crypto . subtle . digest ( "SHA-256" , buf ) ;
374375 const hash = bufferToHex ( digest ) ;
376+ const binaryBase64 = arrayBufferToBase64 ( buf ) ;
375377 return {
376378 vault_id : vaultId ,
377379 path : file . path ,
@@ -390,6 +392,8 @@ export class SyncEngine {
390392 mtime : file . stat . mtime ,
391393 ctime : file . stat . ctime ,
392394 is_binary : true ,
395+ binary_base64 : binaryBase64 ,
396+ mime_type : mimeTypeFromExtension ( file . extension ) ,
393397 } ;
394398 }
395399
@@ -584,6 +588,36 @@ function bufferToHex(buf: ArrayBuffer): string {
584588 return hex ;
585589}
586590
591+ function arrayBufferToBase64 ( buf : ArrayBuffer ) : string {
592+ const bytes = new Uint8Array ( buf ) ;
593+ const chunkSize = 0x8000 ;
594+ let binary = "" ;
595+ for ( let i = 0 ; i < bytes . length ; i += chunkSize ) {
596+ const chunk = bytes . subarray ( i , i + chunkSize ) ;
597+ binary += String . fromCharCode ( ...Array . from ( chunk ) ) ;
598+ }
599+ return btoa ( binary ) ;
600+ }
601+
602+ function mimeTypeFromExtension ( extension : string ) : string | undefined {
603+ const ext = extension . toLowerCase ( ) ;
604+ const mimeByExt : Record < string , string > = {
605+ pdf : "application/pdf" ,
606+ png : "image/png" ,
607+ jpg : "image/jpeg" ,
608+ jpeg : "image/jpeg" ,
609+ gif : "image/gif" ,
610+ webp : "image/webp" ,
611+ svg : "image/svg+xml" ,
612+ txt : "text/plain" ,
613+ csv : "text/csv" ,
614+ docx : "application/vnd.openxmlformats-officedocument.wordprocessingml.document" ,
615+ pptx : "application/vnd.openxmlformats-officedocument.presentationml.presentation" ,
616+ xlsx : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ,
617+ } ;
618+ return mimeByExt [ ext ] ;
619+ }
620+
587621function formatRelative ( ts : number ) : string {
588622 const diff = Date . now ( ) - ts ;
589623 if ( diff < 60_000 ) return "just now" ;
0 commit comments