From 264ed135361bf3e76249f7439b189383e848e409 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Tue, 31 Mar 2026 18:42:12 +0200 Subject: [PATCH] Remove project asset storage implementation --- src/assets/project-asset-storage.ts | 187 ---------------------------- 1 file changed, 187 deletions(-) delete mode 100644 src/assets/project-asset-storage.ts diff --git a/src/assets/project-asset-storage.ts b/src/assets/project-asset-storage.ts deleted file mode 100644 index db882cee..00000000 --- a/src/assets/project-asset-storage.ts +++ /dev/null @@ -1,187 +0,0 @@ -export interface ProjectAssetStorageRecord { - bytes: ArrayBuffer; - mimeType: string; -} - -export interface ProjectAssetStorage { - getAsset(storageKey: string): Promise; - putAsset(storageKey: string, asset: ProjectAssetStorageRecord): Promise; - deleteAsset(storageKey: string): Promise; -} - -export interface ProjectAssetStorageAccessResult { - storage: ProjectAssetStorage | null; - diagnostic: string | null; -} - -const PROJECT_ASSET_DATABASE_NAME = "webeditor3d-project-assets"; -const PROJECT_ASSET_DATABASE_VERSION = 1; -const PROJECT_ASSET_OBJECT_STORE_NAME = "assets"; - -function cloneArrayBuffer(bytes: ArrayBuffer): ArrayBuffer { - return bytes.slice(0); -} - -function getErrorDetail(error: unknown): string { - if (error instanceof Error && error.message.trim().length > 0) { - return error.message.trim(); - } - - return "Unknown error."; -} - -function formatDiagnostic(prefix: string, error: unknown): string { - return `${prefix} ${getErrorDetail(error)}`; -} - -function promisifyRequest(request: IDBRequest): Promise { - return new Promise((resolve, reject) => { - request.addEventListener("success", () => { - resolve(request.result); - }); - request.addEventListener("error", () => { - reject(request.error ?? new Error("IndexedDB request failed.")); - }); - }); -} - -function openIndexedDb(): Promise { - return new Promise((resolve, reject) => { - const request = indexedDB.open(PROJECT_ASSET_DATABASE_NAME, PROJECT_ASSET_DATABASE_VERSION); - - request.addEventListener("upgradeneeded", () => { - const database = request.result; - - if (!database.objectStoreNames.contains(PROJECT_ASSET_OBJECT_STORE_NAME)) { - database.createObjectStore(PROJECT_ASSET_OBJECT_STORE_NAME); - } - }); - - request.addEventListener("success", () => { - resolve(request.result); - }); - - request.addEventListener("error", () => { - reject(request.error ?? new Error("IndexedDB open failed.")); - }); - }); -} - -class IndexedDbProjectAssetStorage implements ProjectAssetStorage { - private readonly databasePromise: Promise; - - constructor(databasePromise: Promise) { - this.databasePromise = databasePromise; - } - - private async withStore(mode: IDBTransactionMode, callback: (store: IDBObjectStore) => IDBRequest): Promise { - const database = await this.databasePromise; - const transaction = database.transaction(PROJECT_ASSET_OBJECT_STORE_NAME, mode); - const store = transaction.objectStore(PROJECT_ASSET_OBJECT_STORE_NAME); - const result = await promisifyRequest(callback(store)); - - await new Promise((resolve, reject) => { - transaction.addEventListener("complete", () => resolve()); - transaction.addEventListener("error", () => reject(transaction.error ?? new Error("IndexedDB transaction failed."))); - transaction.addEventListener("abort", () => reject(transaction.error ?? new Error("IndexedDB transaction aborted."))); - }); - - return result; - } - - async getAsset(storageKey: string): Promise { - const database = await this.databasePromise; - const transaction = database.transaction(PROJECT_ASSET_OBJECT_STORE_NAME, "readonly"); - const store = transaction.objectStore(PROJECT_ASSET_OBJECT_STORE_NAME); - const result = await promisifyRequest(store.get(storageKey)); - - return result === undefined ? null : { bytes: cloneArrayBuffer(result.bytes), mimeType: result.mimeType }; - } - - async putAsset(storageKey: string, asset: ProjectAssetStorageRecord): Promise { - await this.withStore("readwrite", (store) => - store.put( - { - bytes: cloneArrayBuffer(asset.bytes), - mimeType: asset.mimeType - }, - storageKey - ) - ); - } - - async deleteAsset(storageKey: string): Promise { - await this.withStore("readwrite", (store) => store.delete(storageKey)); - } -} - -class InMemoryProjectAssetStorage implements ProjectAssetStorage { - private readonly values = new Map(); - - constructor(initialValues: Record = {}) { - for (const [storageKey, asset] of Object.entries(initialValues)) { - this.values.set(storageKey, { - bytes: cloneArrayBuffer(asset.bytes), - mimeType: asset.mimeType - }); - } - } - - async getAsset(storageKey: string): Promise { - const asset = this.values.get(storageKey); - - if (asset === undefined) { - return null; - } - - return { - bytes: cloneArrayBuffer(asset.bytes), - mimeType: asset.mimeType - }; - } - - async putAsset(storageKey: string, asset: ProjectAssetStorageRecord): Promise { - this.values.set(storageKey, { - bytes: cloneArrayBuffer(asset.bytes), - mimeType: asset.mimeType - }); - } - - async deleteAsset(storageKey: string): Promise { - this.values.delete(storageKey); - } -} - -export function createInMemoryProjectAssetStorage(initialValues: Record = {}): ProjectAssetStorage { - return new InMemoryProjectAssetStorage(initialValues); -} - -export async function getBrowserProjectAssetStorageAccess(): Promise { - if (typeof window === "undefined") { - return { - storage: null, - diagnostic: null - }; - } - - if (typeof indexedDB === "undefined") { - return { - storage: null, - diagnostic: "IndexedDB is unavailable in this browser environment." - }; - } - - try { - const databasePromise = openIndexedDb(); - await databasePromise; - return { - storage: new IndexedDbProjectAssetStorage(databasePromise), - diagnostic: null - }; - } catch (error) { - return { - storage: null, - diagnostic: formatDiagnostic("Project asset storage could not be opened.", error) - }; - } -}