UNPKG

@firesystem/indexeddb

Version:

IndexedDB implementation of Virtual File System

140 lines (123 loc) 4.21 kB
import type { IReactiveFileSystem, IFileSystemCapabilities, } from "@firesystem/core"; // Import type-only para evitar dependência em runtime import type { SourceProvider } from "@workspace-fs/core"; import { IndexedDBFileSystem } from "../IndexedDBFileSystem"; /** * Provider para IndexedDBFileSystem no workspace * Implementa o padrão de providers do VSCode */ export class IndexedDBWorkspaceProvider implements SourceProvider { readonly scheme = "indexeddb"; readonly displayName = "IndexedDB File System"; /** * Cria uma nova instância do IndexedDBFileSystem */ async createFileSystem(config: any): Promise<IReactiveFileSystem> { // Configuração padrão se não fornecida const fsConfig = { dbName: config?.dbName || `firesystem-${Date.now()}`, version: config?.version || 1, storeName: config?.storeName || "files", enableExternalSync: config?.enableExternalSync ?? true, deepChangeDetection: config?.deepChangeDetection ?? false, }; const fs = new IndexedDBFileSystem(fsConfig); // IndexedDB precisa ser inicializado para conectar ao banco await fs.initialize(); return fs; } /** * Valida configuração do IndexedDB provider */ async validateConfiguration( config: any, ): Promise<{ valid: boolean; errors?: string[] }> { const errors: string[] = []; if (config) { // Valida dbName if (config.dbName !== undefined) { if (typeof config.dbName !== "string") { errors.push("dbName must be a string"); } else if (config.dbName.length === 0) { errors.push("dbName cannot be empty"); } else if (!/^[a-zA-Z0-9_-]+$/.test(config.dbName)) { errors.push( "dbName can only contain letters, numbers, hyphens and underscores", ); } } // Valida version if (config.version !== undefined) { if (typeof config.version !== "number") { errors.push("version must be a number"); } else if (config.version < 1) { errors.push("version must be >= 1"); } else if (!Number.isInteger(config.version)) { errors.push("version must be an integer"); } } // Valida storeName if (config.storeName !== undefined) { if (typeof config.storeName !== "string") { errors.push("storeName must be a string"); } else if (config.storeName.length === 0) { errors.push("storeName cannot be empty"); } } // Valida enableExternalSync if ( config.enableExternalSync !== undefined && typeof config.enableExternalSync !== "boolean" ) { errors.push("enableExternalSync must be a boolean"); } // Valida deepChangeDetection if ( config.deepChangeDetection !== undefined && typeof config.deepChangeDetection !== "boolean" ) { errors.push("deepChangeDetection must be a boolean"); } } return { valid: errors.length === 0, errors: errors.length > 0 ? errors : undefined, }; } /** * Retorna as capacidades do IndexedDB FS */ getCapabilities(): IFileSystemCapabilities { return { readonly: false, caseSensitive: true, atomicRename: true, supportsWatch: true, supportsMetadata: true, supportsGlob: true, supportsAtomicOperations: true, maxFileSize: 500 * 1024 * 1024, // 500MB practical limit maxPathLength: 1024, description: "Browser-based persistent storage using IndexedDB. Data survives page reloads and browser restarts.", }; } /** * Limpa e destrói o file system */ async dispose(fs: IReactiveFileSystem): Promise<void> { // Se for IndexedDBFileSystem, chamar dispose para limpar recursos if ("dispose" in fs && typeof fs.dispose === "function") { fs.dispose(); } // Remove todos os event listeners se houver if (fs.events && "removeAllListeners" in fs.events) { fs.events.removeAllListeners(); } } } // Exporta uma instância singleton para conveniência export const indexedDBProvider = new IndexedDBWorkspaceProvider();