Skip to content

Commit 5047527

Browse files
committed
feat: enhance binary attachment handling in sync engine
1 parent 23a52b6 commit 5047527

2 files changed

Lines changed: 41 additions & 1 deletion

File tree

surfsense_obsidian/src/sync-engine.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
587621
function formatRelative(ts: number): string {
588622
const diff = Date.now() - ts;
589623
if (diff < 60_000) return "just now";

surfsense_obsidian/src/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ export interface NotePayload {
8585
size: number;
8686
mtime: number;
8787
ctime: number;
88+
/** Non-markdown attachment marker; enables backend ETL path. */
89+
is_binary?: boolean;
90+
/** Base64-encoded file bytes for binary attachments. */
91+
binary_base64?: string;
92+
/** Optional MIME type hint for backend parsers. */
93+
mime_type?: string;
8894
[key: string]: unknown;
8995
}
9096

0 commit comments

Comments
 (0)