feat(ext/sw): extend GitHost interface with putBlob/getBlob/deleteBlob
Adds the three blob ops to the interface and a BLOB_THRESHOLD_BYTES constant. Both GitHubHost and GiteaHost ship temporary stubs so the build stays green until tasks 3-4 fill in real implementations. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,8 +16,28 @@ export interface GitHost {
|
||||
|
||||
/// List file names in a directory (non-recursive).
|
||||
listDir(path: string): Promise<string[]>;
|
||||
|
||||
/// 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<string>;
|
||||
|
||||
/// 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<Uint8Array>;
|
||||
|
||||
/// Delete a blob from the repo. Currently identical to deleteFile;
|
||||
/// kept distinct for symmetry with putBlob.
|
||||
deleteBlob(path: string, message: string): Promise<void>;
|
||||
}
|
||||
|
||||
/// 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 = '';
|
||||
|
||||
@@ -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<string> {
|
||||
throw new Error(`GiteaHost.putBlob not implemented — Task 4`);
|
||||
}
|
||||
|
||||
async getBlob(path: string): Promise<Uint8Array> {
|
||||
return this.readFile(path);
|
||||
}
|
||||
|
||||
async deleteBlob(path: string, message: string): Promise<void> {
|
||||
return this.deleteFile(path, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<string> {
|
||||
throw new Error(`GitHubHost.putBlob not implemented — Task 3`);
|
||||
}
|
||||
|
||||
async getBlob(path: string): Promise<Uint8Array> {
|
||||
return this.readFile(path);
|
||||
}
|
||||
|
||||
async deleteBlob(path: string, message: string): Promise<void> {
|
||||
return this.deleteFile(path, message);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user