diff --git a/extension/src/service-worker/git-host.ts b/extension/src/service-worker/git-host.ts index e856d82..cdb1e78 100644 --- a/extension/src/service-worker/git-host.ts +++ b/extension/src/service-worker/git-host.ts @@ -16,8 +16,28 @@ export interface GitHost { /// List file names in a directory (non-recursive). listDir(path: string): Promise; + + /// Write an opaque binary blob to the repo. Optimized for large + /// attachments — implementations switch from Contents API to Git + /// Data API when content exceeds BLOB_THRESHOLD_BYTES. + /// Returns the path that was written (same as input, for chaining). + putBlob(path: string, content: Uint8Array, message: string): Promise; + + /// Read an opaque binary blob from the repo. Same semantics as + /// readFile for current sizes. Distinct method so we can later add + /// streaming/chunked reads for very large blobs. + getBlob(path: string): Promise; + + /// Delete a blob from the repo. Currently identical to deleteFile; + /// kept distinct for symmetry with putBlob. + deleteBlob(path: string, message: string): Promise; } +/// Pre-base64 byte size at which putBlob switches from Contents API to +/// Git Data API. 900 KB leaves headroom for base64 inflation (1.33×) and +/// JSON wrapping under both GitHub's and Gitea's Contents API soft-limits. +export const BLOB_THRESHOLD_BYTES = 900 * 1024; + /// Convert a Uint8Array to a base64 string (works in service worker context). export function uint8ArrayToBase64(bytes: Uint8Array): string { let binary = ''; diff --git a/extension/src/service-worker/gitea.ts b/extension/src/service-worker/gitea.ts index 4f9582d..7344f2c 100644 --- a/extension/src/service-worker/gitea.ts +++ b/extension/src/service-worker/gitea.ts @@ -111,4 +111,16 @@ export class GiteaHost implements GitHost { if (!Array.isArray(json)) return []; return json.map((item: { name: string }) => item.name); } + + async putBlob(_path: string, _content: Uint8Array, _message: string): Promise { + throw new Error(`GiteaHost.putBlob not implemented — Task 4`); + } + + async getBlob(path: string): Promise { + return this.readFile(path); + } + + async deleteBlob(path: string, message: string): Promise { + return this.deleteFile(path, message); + } } diff --git a/extension/src/service-worker/github.ts b/extension/src/service-worker/github.ts index 7dcee89..2e9df09 100644 --- a/extension/src/service-worker/github.ts +++ b/extension/src/service-worker/github.ts @@ -105,4 +105,16 @@ export class GitHubHost implements GitHost { if (!Array.isArray(json)) return []; return json.map((item: { name: string }) => item.name); } + + async putBlob(_path: string, _content: Uint8Array, _message: string): Promise { + throw new Error(`GitHubHost.putBlob not implemented — Task 3`); + } + + async getBlob(path: string): Promise { + return this.readFile(path); + } + + async deleteBlob(path: string, message: string): Promise { + return this.deleteFile(path, message); + } }