import type { StorageAdapter } from "@noya-app/git-remote"; import type { AssetManager } from "./AssetManager"; import { GIT_BUNDLE_CONTENT_TYPE } from "./constants"; /** * A StorageAdapter that stores git bundles as assets using the AssetManager. * This is used for local/offline git storage in localStorageSync. */ export class LocalAssetStorageAdapter implements StorageAdapter { constructor(private assetManager: AssetManager) {} async initialize(): Promise { // Ensure assets are loaded await this.assetManager.fetch(); } private findBundleAsset(id: string) { const assets = this.assetManager.assets$.get(); return assets.find( (a) => (a.id === id || a.stableId === id) && a.contentType === GIT_BUNDLE_CONTENT_TYPE ); } async readBundle(id: string): Promise { const asset = this.findBundleAsset(id); if (!asset || !asset.url) { return null; } try { const response = await fetch(asset.url); if (!response.ok) { console.error(`Failed to fetch bundle ${id}: ${response.status}`); return null; } const buffer = await response.arrayBuffer(); return new Uint8Array(buffer); } catch (error) { console.error(`Error fetching bundle ${id}:`, error); return null; } } async writeBundle(id: string, data: Uint8Array): Promise { const existingAsset = this.findBundleAsset(id); try { if (existingAsset) { // Update existing asset using its actual id await this.assetManager.update(existingAsset.id, { data, contentType: GIT_BUNDLE_CONTENT_TYPE, }); } else { // Create new asset with the bundle id as stableId await this.assetManager.create({ data, contentType: GIT_BUNDLE_CONTENT_TYPE, stableId: id, }); } } catch (error) { console.error(`Error writing bundle ${id}:`, error); throw error; } } async listBundleIds(): Promise { const assets = this.assetManager.assets$.get(); // Return stableId as the bundle id since that's what we use as the identifier return assets .filter((a) => a.contentType === GIT_BUNDLE_CONTENT_TYPE) .map((a) => a.stableId); } async deleteBundle(id: string): Promise { const asset = this.findBundleAsset(id); if (!asset) { return; // Already deleted or doesn't exist } try { await this.assetManager.delete(asset.id); } catch (error) { console.error(`Error deleting bundle ${id}:`, error); throw error; } } }