{"version":3,"sources":["../src/index.ts","../src/IndexedDBFileSystem.ts"],"sourcesContent":["export { IndexedDBFileSystem } from \"./IndexedDBFileSystem\";\nexport type { IndexedDBConfig } from \"./types\";\n","import type {\n  FileEntry,\n  FileStat,\n  FileMetadata,\n  FSEvent,\n  Disposable,\n  FileSystemEventPayloads,\n  IFileSystemCapabilities,\n} from \"@firesystem/core\";\nimport {\n  normalizePath,\n  dirname,\n  basename,\n  join,\n  TypedEventEmitter,\n  FileSystemEvents,\n  BaseFileSystem,\n} from \"@firesystem/core\";\nimport type { IndexedDBConfig } from \"./types\";\n\ninterface StoredFile {\n  path: string;\n  type: \"file\" | \"directory\";\n  content?: any;\n  size: number;\n  created: Date;\n  modified: Date;\n  metadata?: FileMetadata;\n  parent: string;\n}\n\ninterface WatchListener {\n  id: string;\n  pattern: string;\n  callback: (event: FSEvent) => void;\n}\n\ninterface FileSnapshot {\n  path: string;\n  type: \"file\" | \"directory\";\n  modified: Date;\n  size: number;\n  contentHash?: string;\n  metadataHash?: string;\n}\n\nexport class IndexedDBFileSystem extends BaseFileSystem {\n  private db: IDBDatabase | null = null;\n  private config: Required<Omit<IndexedDBConfig, \"enableExternalSync\" | \"deepChangeDetection\">> & { \n    enableExternalSync: boolean;\n    deepChangeDetection: boolean;\n  };\n  private watchers: WatchListener[] = [];\n  private isInitialized = false;\n  public readonly events = new TypedEventEmitter<FileSystemEventPayloads>();\n  private broadcastChannel: BroadcastChannel | null = null;\n  private fileSnapshots: Map<string, FileSnapshot> = new Map();\n  private pollingInterval: NodeJS.Timeout | null = null;\n  private enableExternalSync = true;\n  private deepChangeDetection = false;\n\n  // Capabilities do IndexedDB\n  readonly capabilities: IFileSystemCapabilities = {\n    readonly: false,\n    caseSensitive: true,\n    atomicRename: false, // IndexedDB não tem rename atômico verdadeiro\n    supportsWatch: true,\n    supportsMetadata: true,\n    maxFileSize: undefined, // Depende do browser e quota\n    maxPathLength: 1024\n  };\n\n  constructor(config: IndexedDBConfig) {\n    super();\n    this.config = {\n      dbName: config.dbName,\n      version: config.version || 1,\n      storeName: config.storeName || \"files\",\n      enableExternalSync: config.enableExternalSync ?? true,\n      deepChangeDetection: config.deepChangeDetection ?? false,\n    };\n    this.enableExternalSync = config.enableExternalSync ?? true;\n    this.deepChangeDetection = config.deepChangeDetection ?? false;\n    \n    if (this.enableExternalSync && typeof BroadcastChannel !== \"undefined\") {\n      this.setupBroadcastChannel();\n    }\n  }\n\n  private async ensureDB(): Promise<IDBDatabase> {\n    if (this.db && this.db.name === this.config.dbName) {\n      return this.db;\n    }\n\n    return new Promise((resolve, reject) => {\n      const request = indexedDB.open(this.config.dbName, this.config.version);\n\n      request.onerror = () => {\n        reject(new Error(`Failed to open IndexedDB: ${request.error}`));\n      };\n\n      request.onsuccess = async () => {\n        this.db = request.result;\n        this.isInitialized = true;\n\n        // Handle connection close\n        this.db.onclose = () => {\n          this.db = null;\n          this.isInitialized = false;\n        };\n\n        // Ensure root exists\n        await this.ensureRootExists();\n\n        resolve(this.db);\n      };\n\n      request.onupgradeneeded = (event) => {\n        const db = (event.target as IDBOpenDBRequest).result;\n\n        // Create object store if it doesn't exist\n        if (!db.objectStoreNames.contains(this.config.storeName)) {\n          const store = db.createObjectStore(this.config.storeName, {\n            keyPath: \"path\",\n          });\n\n          // Create indexes for efficient queries\n          store.createIndex(\"type\", \"type\", { unique: false });\n          store.createIndex(\"parent\", \"parent\", { unique: false });\n          store.createIndex(\"modified\", \"modified\", { unique: false });\n\n          // Add root directory\n          const now = new Date();\n          store.add({\n            path: \"/\",\n            type: \"directory\",\n            size: 0,\n            created: now,\n            modified: now,\n            parent: \"\",\n          });\n        }\n      };\n    });\n  }\n\n  async initialize(): Promise<void> {\n    const startTime = Date.now();\n    this.events.emit(FileSystemEvents.INITIALIZING, undefined as any);\n\n    try {\n      // Ensure database connection\n      const db = await this.ensureDB();\n\n      // Load ALL files from database\n      const allFiles = await this.loadAllFiles();\n      const fileCount = allFiles.length;\n\n      // Emit progress for each file loaded\n      for (let i = 0; i < allFiles.length; i++) {\n        const file = allFiles[i];\n\n        // Emit individual file events\n        if (file.type === \"file\") {\n          this.events.emit(FileSystemEvents.FILE_READ, {\n            path: file.path,\n            size: file.size,\n          });\n        } else {\n          this.events.emit(FileSystemEvents.DIR_READ, {\n            path: file.path,\n            count: 0, // We'll count children later if needed\n          });\n        }\n\n        // Emit progress\n        this.events.emit(FileSystemEvents.INIT_PROGRESS, {\n          loaded: i + 1,\n          total: fileCount,\n          phase: \"loading-files\",\n        });\n      }\n\n      this.events.emit(FileSystemEvents.INITIALIZED, {\n        duration: Date.now() - startTime,\n      });\n    } catch (error) {\n      this.events.emit(FileSystemEvents.INIT_ERROR, {\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  private async loadAllFiles(): Promise<StoredFile[]> {\n    const db = await this.ensureDB();\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([this.config.storeName], \"readonly\");\n      const store = transaction.objectStore(this.config.storeName);\n      const request = store.getAll();\n\n      request.onsuccess = () => {\n        const files = request.result as StoredFile[];\n        // Exclude root directory from the list\n        const userFiles = files.filter((f) => f.path !== \"/\");\n        resolve(userFiles);\n      };\n\n      request.onerror = () => {\n        reject(new Error(`Failed to load files: ${request.error}`));\n      };\n    });\n  }\n\n  async readFile(path: string): Promise<FileEntry> {\n    const normalized = normalizePath(path);\n    const db = await this.ensureDB();\n\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([this.config.storeName], \"readonly\");\n      const store = transaction.objectStore(this.config.storeName);\n      const request = store.get(normalized);\n\n      request.onsuccess = () => {\n        const file = request.result as StoredFile;\n        if (!file) {\n          reject(\n            new Error(`ENOENT: no such file or directory, open '${path}'`),\n          );\n          return;\n        }\n        if (file.type === \"directory\") {\n          reject(\n            new Error(\n              `EISDIR: illegal operation on a directory, read '${path}'`,\n            ),\n          );\n          return;\n        }\n        resolve({\n          path: file.path,\n          name: basename(file.path),\n          type: file.type,\n          size: file.size,\n          created: file.created,\n          modified: file.modified,\n          metadata: file.metadata,\n          content: file.content,\n        });\n      };\n\n      request.onerror = () => {\n        reject(new Error(`Failed to read file: ${request.error}`));\n      };\n    });\n  }\n\n  async writeFile(\n    path: string,\n    content: any,\n    metadata?: FileMetadata,\n  ): Promise<FileEntry> {\n    const normalized = normalizePath(path);\n    const db = await this.ensureDB();\n\n    // Ensure parent directory exists\n    await this.ensureParentExists(normalized);\n\n    const now = new Date();\n    const size = this.calculateSize(content);\n\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([this.config.storeName], \"readwrite\");\n      const store = transaction.objectStore(this.config.storeName);\n\n      // Check if file exists to preserve created date\n      const getRequest = store.get(normalized);\n\n      getRequest.onsuccess = () => {\n        const existing = getRequest.result as StoredFile | undefined;\n        const isUpdate = !!existing;\n\n        const storedFile: StoredFile = {\n          path: normalized,\n          type: \"file\",\n          content,\n          size,\n          created: existing?.created || now,\n          modified: now,\n          metadata,\n          parent: dirname(normalized),\n        } as StoredFile;\n\n        const putRequest = store.put(storedFile);\n\n        putRequest.onsuccess = () => {\n          const entry: FileEntry = {\n            path: normalized,\n            name: basename(normalized),\n            type: \"file\",\n            size,\n            created: storedFile.created,\n            modified: storedFile.modified,\n            metadata,\n            content,\n          };\n\n          // Notify watchers\n          const event = {\n            type: isUpdate ? \"updated\" : \"created\" as \"updated\" | \"created\",\n            path: normalized,\n            timestamp: now,\n          };\n          this.notifyWatchers(event);\n          \n          // Broadcast to other tabs/windows\n          this.broadcastChange({\n            ...event,\n            size,\n            isDirectory: false,\n            fileType: \"file\" as const,\n          });\n\n          resolve(entry);\n        };\n\n        putRequest.onerror = () => {\n          reject(new Error(`Failed to write file: ${putRequest.error}`));\n        };\n      };\n\n      getRequest.onerror = () => {\n        reject(new Error(`Failed to check existing file: ${getRequest.error}`));\n      };\n    });\n  }\n\n  async deleteFile(path: string): Promise<void> {\n    const normalized = normalizePath(path);\n    const db = await this.ensureDB();\n\n    // First check if it exists and get type\n    const file = await this.stat(normalized).catch(() => null);\n    if (!file) {\n      throw new Error(`ENOENT: no such file or directory, unlink '${path}'`);\n    }\n\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([this.config.storeName], \"readwrite\");\n      const store = transaction.objectStore(this.config.storeName);\n\n      if (file.type === \"directory\") {\n        // Check if directory is empty\n        const index = store.index(\"parent\");\n        const request = index.count(normalized);\n\n        request.onsuccess = () => {\n          if (request.result > 0) {\n            reject(\n              new Error(`ENOTEMPTY: directory not empty, rmdir '${path}'`),\n            );\n            return;\n          }\n\n          // Directory is empty, delete it\n          const deleteRequest = store.delete(normalized);\n\n          deleteRequest.onsuccess = () => {\n            const event = {\n              type: \"deleted\" as const,\n              path: normalized,\n              timestamp: new Date(),\n            };\n            this.notifyWatchers(event);\n            this.broadcastChange(event);\n            resolve();\n          };\n\n          deleteRequest.onerror = () => {\n            reject(\n              new Error(`Failed to delete directory: ${deleteRequest.error}`),\n            );\n          };\n        };\n\n        request.onerror = () => {\n          reject(\n            new Error(`Failed to check directory contents: ${request.error}`),\n          );\n        };\n      } else {\n        // It's a file, delete directly\n        const request = store.delete(normalized);\n\n        request.onsuccess = () => {\n          const event = {\n            type: \"deleted\" as const,\n            path: normalized,\n            timestamp: new Date(),\n          };\n          this.notifyWatchers(event);\n          this.broadcastChange(event);\n          resolve();\n        };\n\n        request.onerror = () => {\n          reject(new Error(`Failed to delete file: ${request.error}`));\n        };\n      }\n    });\n  }\n\n  async exists(path: string): Promise<boolean> {\n    const normalized = normalizePath(path);\n    const db = await this.ensureDB();\n\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([this.config.storeName], \"readonly\");\n      const store = transaction.objectStore(this.config.storeName);\n      const request = store.count(normalized);\n\n      request.onsuccess = () => {\n        resolve(request.result > 0);\n      };\n\n      request.onerror = () => {\n        reject(new Error(`Failed to check existence: ${request.error}`));\n      };\n    });\n  }\n\n  async readDir(path: string): Promise<FileEntry[]> {\n    const normalized = normalizePath(path);\n    const db = await this.ensureDB();\n\n    // First check if directory exists\n    if (normalized !== \"/\" && !(await this.exists(normalized))) {\n      throw new Error(`ENOENT: no such file or directory, scandir '${path}'`);\n    }\n\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([this.config.storeName], \"readonly\");\n      const store = transaction.objectStore(this.config.storeName);\n      const index = store.index(\"parent\");\n      const request = index.getAll(normalized);\n\n      request.onsuccess = () => {\n        const files = request.result as StoredFile[];\n        const entries = files.map((file) => ({\n          path: file.path,\n          name: basename(file.path),\n          type: file.type,\n          size: file.size,\n          created: file.created,\n          modified: file.modified,\n          metadata: file.metadata,\n        }));\n\n        resolve(entries);\n      };\n\n      request.onerror = () => {\n        reject(new Error(`Failed to read directory: ${request.error}`));\n      };\n    });\n  }\n\n  async mkdir(path: string, recursive: boolean = false): Promise<FileEntry> {\n    const normalized = normalizePath(path);\n\n    if (normalized === \"/\") {\n      throw new Error(`EEXIST: file already exists, mkdir '${path}'`);\n    }\n\n    const db = await this.ensureDB();\n\n    // Check if already exists\n    if (await this.exists(normalized)) {\n      throw new Error(`EEXIST: file already exists, mkdir '${path}'`);\n    }\n\n    // Ensure parent exists if not recursive\n    const parent = dirname(normalized);\n    if (!recursive && parent !== \"/\" && !(await this.exists(parent))) {\n      throw new Error(`ENOENT: no such file or directory, mkdir '${path}'`);\n    }\n\n    // Create parent directories if recursive\n    if (recursive && parent !== \"/\" && !(await this.exists(parent))) {\n      await this.mkdir(parent, true);\n    }\n\n    const now = new Date();\n\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([this.config.storeName], \"readwrite\");\n      const store = transaction.objectStore(this.config.storeName);\n\n      const storedFile: StoredFile = {\n        path: normalized,\n        type: \"directory\",\n        size: 0,\n        created: now,\n        modified: now,\n        parent: dirname(normalized),\n      } as StoredFile;\n\n      const request = store.add(storedFile);\n\n      request.onsuccess = () => {\n        const entry: FileEntry = {\n          path: normalized,\n          name: basename(normalized),\n          type: \"directory\",\n          size: 0,\n          created: now,\n          modified: now,\n        };\n\n        const event = {\n          type: \"created\" as const,\n          path: normalized,\n          timestamp: now,\n        };\n        this.notifyWatchers(event);\n        this.broadcastChange({\n          ...event,\n          isDirectory: true,\n          fileType: \"directory\" as const,\n        });\n\n        resolve(entry);\n      };\n\n      request.onerror = () => {\n        reject(new Error(`Failed to create directory: ${request.error}`));\n      };\n    });\n  }\n\n  async rmdir(path: string, recursive: boolean = false): Promise<void> {\n    const normalized = normalizePath(path);\n\n    if (normalized === \"/\") {\n      throw new Error(`EBUSY: resource busy or locked, rmdir '${path}'`);\n    }\n\n    const db = await this.ensureDB();\n\n    // Check if directory exists\n    const stat = await this.stat(normalized).catch(() => null);\n    if (!stat) {\n      throw new Error(`ENOENT: no such file or directory, rmdir '${path}'`);\n    }\n    if (stat.type !== \"directory\") {\n      throw new Error(`ENOTDIR: not a directory, rmdir '${path}'`);\n    }\n\n    if (recursive) {\n      // Delete all contents recursively\n      await this.deleteRecursive(normalized);\n    } else {\n      // Check if empty\n      const contents = await this.readDir(normalized);\n      if (contents.length > 0) {\n        throw new Error(`ENOTEMPTY: directory not empty, rmdir '${path}'`);\n      }\n    }\n\n    // Delete the directory itself\n    await this.deleteFile(normalized);\n  }\n\n  async rename(oldPath: string, newPath: string): Promise<FileEntry> {\n    const oldNormalized = normalizePath(oldPath);\n    const newNormalized = normalizePath(newPath);\n    const db = await this.ensureDB();\n\n    // Get the file/directory\n    const oldStat = await this.stat(oldNormalized);\n\n    // Ensure new parent exists\n    await this.ensureParentExists(newNormalized);\n\n    // Check if new path already exists\n    if (await this.exists(newNormalized)) {\n      throw new Error(\n        `EEXIST: file already exists, rename '${oldPath}' -> '${newPath}'`,\n      );\n    }\n\n    const now = new Date();\n\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([this.config.storeName], \"readwrite\");\n      const store = transaction.objectStore(this.config.storeName);\n\n      // If it's a directory, we need to update all children\n      if (oldStat.type === \"directory\") {\n        // Get all descendants\n        const request = store.openCursor();\n        const updates: StoredFile[] = [];\n\n        request.onsuccess = (event) => {\n          const cursor = (event.target as IDBRequest).result;\n\n          if (cursor) {\n            const file = cursor.value as StoredFile;\n\n            // Check if this file is under the old path\n            if (\n              file.path.startsWith(oldNormalized + \"/\") ||\n              file.path === oldNormalized\n            ) {\n              const newFilePath = file.path.replace(\n                oldNormalized,\n                newNormalized,\n              );\n              updates.push({\n                ...file,\n                path: newFilePath,\n                parent: dirname(newFilePath),\n                modified: file.path === oldNormalized ? now : file.modified,\n              });\n            }\n\n            cursor.continue();\n          } else {\n            // All files collected, now update them\n            let completed = 0;\n            const total = updates.length;\n\n            if (total === 0) {\n              reject(new Error(`Directory not found: ${oldPath}`));\n              return;\n            }\n\n            updates.forEach((file) => {\n              // Delete old entry\n              store.delete(file.path.replace(newNormalized, oldNormalized));\n\n              // Add new entry\n              const addRequest = store.add(file);\n\n              addRequest.onsuccess = () => {\n                completed++;\n                if (completed === total) {\n                  const entry = updates.find((f) => f.path === newNormalized)!;\n\n                  const event = {\n                    type: \"renamed\" as const,\n                    path: newNormalized,\n                    oldPath: oldNormalized,\n                    timestamp: now,\n                  };\n                  this.notifyWatchers(event);\n                  this.broadcastChange(event);\n\n                  resolve({\n                    path: entry.path,\n                    name: basename(entry.path),\n                    type: entry.type,\n                    size: entry.size,\n                    created: entry.created,\n                    modified: entry.modified,\n                    metadata: entry.metadata,\n                  });\n                }\n              };\n\n              addRequest.onerror = () => {\n                reject(\n                  new Error(`Failed to rename directory: ${addRequest.error}`),\n                );\n              };\n            });\n          }\n        };\n\n        request.onerror = () => {\n          reject(new Error(`Failed to read files: ${request.error}`));\n        };\n      } else {\n        // It's a file, simpler case\n        const getRequest = store.get(oldNormalized);\n\n        getRequest.onsuccess = () => {\n          const file = getRequest.result as StoredFile;\n          if (!file) {\n            reject(new Error(`File not found: ${oldPath}`));\n            return;\n          }\n\n          // Delete old entry\n          store.delete(oldNormalized);\n\n          // Create new entry\n          const newFile: StoredFile = {\n            ...file,\n            path: newNormalized,\n            parent: dirname(newNormalized),\n            modified: now,\n          };\n\n          const addRequest = store.add(newFile);\n\n          addRequest.onsuccess = () => {\n            const entry: FileEntry = {\n              path: newNormalized,\n              name: basename(newNormalized),\n              type: file.type,\n              size: file.size,\n              created: file.created,\n              modified: now,\n              metadata: file.metadata,\n              content: file.content,\n            };\n\n            const event = {\n              type: \"renamed\" as const,\n              path: newNormalized,\n              oldPath: oldNormalized,\n              timestamp: now,\n            };\n            this.notifyWatchers(event);\n            this.broadcastChange(event);\n\n            resolve(entry);\n          };\n\n          addRequest.onerror = () => {\n            reject(new Error(`Failed to rename file: ${addRequest.error}`));\n          };\n        };\n\n        getRequest.onerror = () => {\n          reject(new Error(`Failed to read file: ${getRequest.error}`));\n        };\n      }\n    });\n  }\n\n  async move(sourcePaths: string[], targetPath: string): Promise<void> {\n    const targetNormalized = normalizePath(targetPath);\n\n    // Ensure target is a directory\n    const targetStat = await this.stat(targetNormalized).catch(() => null);\n    if (!targetStat || targetStat.type !== \"directory\") {\n      throw new Error(`ENOTDIR: not a directory, move to '${targetPath}'`);\n    }\n\n    for (const sourcePath of sourcePaths) {\n      const name = basename(sourcePath);\n      const newPath = join(targetNormalized, name);\n      await this.rename(sourcePath, newPath);\n    }\n  }\n\n  async copy(sourcePath: string, targetPath: string): Promise<FileEntry> {\n    const sourceNormalized = normalizePath(sourcePath);\n    const targetNormalized = normalizePath(targetPath);\n\n    // Read source file\n    const source = await this.readFile(sourceNormalized);\n\n    // Write to target\n    return this.writeFile(targetNormalized, source.content, source.metadata);\n  }\n\n  watch(pattern: string, callback: (event: FSEvent) => void): Disposable {\n    const id = this.generateWatcherId();\n    const listener: WatchListener = { id, pattern, callback };\n\n    this.watchers.push(listener);\n\n    return {\n      dispose: () => {\n        const index = this.watchers.findIndex((w) => w.id === id);\n        if (index !== -1) {\n          this.watchers.splice(index, 1);\n        }\n      },\n    };\n  }\n\n  async stat(path: string): Promise<FileStat> {\n    const normalized = normalizePath(path);\n    const db = await this.ensureDB();\n\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([this.config.storeName], \"readonly\");\n      const store = transaction.objectStore(this.config.storeName);\n      const request = store.get(normalized);\n\n      request.onsuccess = () => {\n        const file = request.result as StoredFile;\n        if (!file) {\n          reject(\n            new Error(`ENOENT: no such file or directory, stat '${path}'`),\n          );\n          return;\n        }\n\n        resolve({\n          path: file.path,\n          size: file.size,\n          type: file.type,\n          created: file.created,\n          modified: file.modified,\n          readonly: false, // Sempre false em IndexedDB\n        });\n      };\n\n      request.onerror = () => {\n        reject(new Error(`Failed to stat file: ${request.error}`));\n      };\n    });\n  }\n\n  async glob(pattern: string): Promise<string[]> {\n    const db = await this.ensureDB();\n\n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([this.config.storeName], \"readonly\");\n      const store = transaction.objectStore(this.config.storeName);\n      const request = store.getAll();\n\n      request.onsuccess = () => {\n        const files = request.result as StoredFile[];\n        const paths = files\n          .map((file) => file.path)\n          .filter((path) => this.matchesPattern(path, pattern))\n          .sort();\n\n        resolve(paths);\n      };\n\n      request.onerror = () => {\n        reject(new Error(`Failed to glob: ${request.error}`));\n      };\n    });\n  }\n\n  async clear(): Promise<void> {\n    const startTime = Date.now();\n    const operationId = `clear-${startTime}`;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"clear\",\n      id: operationId,\n    });\n    this.events.emit(FileSystemEvents.STORAGE_CLEARING, undefined as any);\n\n    try {\n      const db = await this.ensureDB();\n\n      await new Promise<void>((resolve, reject) => {\n        const transaction = db.transaction(\n          [this.config.storeName],\n          \"readwrite\",\n        );\n        const store = transaction.objectStore(this.config.storeName);\n        const request = store.clear();\n\n        request.onsuccess = () => {\n          // Always ensure root directory exists after clear\n          const rootTransaction = db.transaction(\n            [this.config.storeName],\n            \"readwrite\",\n          );\n          const rootStore = rootTransaction.objectStore(this.config.storeName);\n          const now = new Date();\n\n          const rootDir: StoredFile = {\n            path: \"/\",\n            type: \"directory\",\n            size: 0,\n            created: now,\n            modified: now,\n            parent: \"\",\n          };\n\n          const rootRequest = rootStore.add(rootDir);\n          rootRequest.onsuccess = () => resolve();\n          rootRequest.onerror = () =>\n            reject(new Error(`Failed to recreate root: ${rootRequest.error}`));\n        };\n\n        request.onerror = () => {\n          reject(new Error(`Failed to clear store: ${request.error}`));\n        };\n      });\n\n      const duration = Date.now() - startTime;\n      this.events.emit(FileSystemEvents.STORAGE_CLEARED, { duration });\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"clear\",\n        id: operationId,\n        duration,\n      });\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"clear\",\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  async size(): Promise<number> {\n    const startTime = Date.now();\n    const operationId = `size-${startTime}`;\n\n    this.events.emit(FileSystemEvents.OPERATION_START, {\n      operation: \"size\",\n      id: operationId,\n    });\n\n    try {\n      const db = await this.ensureDB();\n\n      const totalSize = await new Promise<number>((resolve, reject) => {\n        const transaction = db.transaction([this.config.storeName], \"readonly\");\n        const store = transaction.objectStore(this.config.storeName);\n        const request = store.getAll();\n\n        request.onsuccess = () => {\n          const files = request.result as StoredFile[];\n          const size = files.reduce((sum, file) => sum + file.size, 0);\n          resolve(size);\n        };\n\n        request.onerror = () => {\n          reject(new Error(`Failed to calculate size: ${request.error}`));\n        };\n      });\n\n      this.events.emit(FileSystemEvents.STORAGE_SIZE_CALCULATED, {\n        size: totalSize,\n      });\n      this.events.emit(FileSystemEvents.OPERATION_END, {\n        operation: \"size\",\n        id: operationId,\n        duration: Date.now() - startTime,\n      });\n\n      return totalSize;\n    } catch (error) {\n      this.events.emit(FileSystemEvents.OPERATION_ERROR, {\n        operation: \"size\",\n        error: error as Error,\n      });\n      throw error;\n    }\n  }\n\n  // Helper methods\n\n  private async calculateHash(data: any): Promise<string> {\n    // Simple hash for content comparison\n    const str = typeof data === 'string' ? data : JSON.stringify(data);\n    let hash = 0;\n    for (let i = 0; i < str.length; i++) {\n      const char = str.charCodeAt(i);\n      hash = ((hash << 5) - hash) + char;\n      hash = hash & hash; // Convert to 32-bit integer\n    }\n    return hash.toString(36);\n  }\n\n  private calculateSize(content: any): number {\n    if (content === null || content === undefined) {\n      return 0;\n    }\n    if (typeof content === \"string\") {\n      return new Blob([content]).size;\n    }\n    if (content instanceof ArrayBuffer) {\n      return content.byteLength;\n    }\n    if (content instanceof Blob) {\n      return content.size;\n    }\n    if (typeof content === \"object\") {\n      return new Blob([JSON.stringify(content)]).size;\n    }\n    return 0;\n  }\n\n  private async ensureParentExists(path: string): Promise<void> {\n    const parent = dirname(path);\n    if (parent === \"/\" || parent === path) return;\n\n    if (!(await this.exists(parent))) {\n      throw new Error(`ENOENT: no such file or directory, open '${path}'`);\n    }\n  }\n\n  private async deleteRecursive(path: string): Promise<void> {\n    const entries = await this.readDir(path);\n\n    for (const entry of entries) {\n      if (entry.type === \"directory\") {\n        await this.deleteRecursive(entry.path);\n      }\n      await this.deleteFile(entry.path);\n    }\n  }\n\n  private matchesPattern(path: string, pattern: string): boolean {\n    // Handle simple cases\n    if (pattern === \"**\" || pattern === \"**/*\") {\n      return true;\n    }\n\n    if (pattern === \"*\") {\n      // * should only match files in root directory\n      return path.split(\"/\").length === 2 && path !== \"/\";\n    }\n\n    // Convert glob pattern to regex\n    let regex = pattern\n      // Escape special regex characters except glob ones\n      .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n      // Handle ** (matches any number of directories)\n      .replace(/\\*\\*/g, \"___GLOBSTAR___\")\n      // Handle * (matches any characters except /)\n      .replace(/\\*/g, \"[^/]*\")\n      // Handle ? (matches single character except /)\n      .replace(/\\?/g, \"[^/]\")\n      // Restore ** handling\n      .replace(/___GLOBSTAR___\\//g, \"(.*/)?\")\n      .replace(/\\/___GLOBSTAR___/g, \"(/.*)?\")\n      .replace(/___GLOBSTAR___/g, \".*\");\n\n    // Anchor the pattern\n    regex = \"^\" + regex + \"$\";\n\n    return new RegExp(regex).test(path);\n  }\n\n  private notifyWatchers(event: FSEvent): void {\n    for (const watcher of this.watchers) {\n      if (this.matchesPattern(event.path, watcher.pattern)) {\n        try {\n          watcher.callback(event);\n        } catch (error) {\n          console.error(\n            `Error in watch callback for pattern \"${watcher.pattern}\":`,\n            error,\n          );\n        }\n      }\n    }\n  }\n\n  private generateWatcherId(): string {\n    return `watch_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n  }\n\n  private async ensureRootExists(): Promise<void> {\n    if (!this.db) return;\n\n    const transaction = this.db.transaction(\n      [this.config.storeName],\n      \"readonly\",\n    );\n    const store = transaction.objectStore(this.config.storeName);\n    const request = store.get(\"/\");\n\n    return new Promise((resolve) => {\n      request.onsuccess = async () => {\n        if (!request.result) {\n          // Root doesn't exist, create it\n          const writeTransaction = this.db!.transaction(\n            [this.config.storeName],\n            \"readwrite\",\n          );\n          const writeStore = writeTransaction.objectStore(\n            this.config.storeName,\n          );\n          const now = new Date();\n\n          await new Promise<void>((res, rej) => {\n            const addRequest = writeStore.add({\n              path: \"/\",\n              type: \"directory\",\n              size: 0,\n              created: now,\n              modified: now,\n              parent: \"\",\n            });\n\n            addRequest.onsuccess = () => res();\n            addRequest.onerror = () =>\n              rej(new Error(\"Failed to create root directory\"));\n          });\n        }\n        resolve();\n      };\n\n      request.onerror = () => resolve(); // Ignore errors, we'll try next time\n    });\n  }\n\n  private setupBroadcastChannel(): void {\n    this.broadcastChannel = new BroadcastChannel(`vfs-${this.config.dbName}`);\n    \n    this.broadcastChannel.onmessage = (event) => {\n      const { type, path, oldPath, timestamp } = event.data;\n      \n      // Notify local watchers about external changes\n      this.notifyWatchers({\n        type,\n        path,\n        oldPath,\n        timestamp: new Date(timestamp),\n      });\n      \n      // Emit events for external changes\n      switch (type) {\n        case \"created\":\n          if (event.data.isDirectory) {\n            this.events.emit(FileSystemEvents.DIR_CREATED, { path });\n          } else {\n            this.events.emit(FileSystemEvents.FILE_WRITTEN, { \n              path, \n              size: event.data.size || 0 \n            });\n          }\n          break;\n        case \"updated\":\n          this.events.emit(FileSystemEvents.FILE_WRITTEN, { \n            path, \n            size: event.data.size || 0 \n          });\n          break;\n        case \"deleted\":\n          this.events.emit(FileSystemEvents.FILE_DELETED, { path });\n          break;\n        case \"renamed\":\n          // Emit as both deleted and created since there's no FILE_RENAMED event\n          if (oldPath) {\n            this.events.emit(FileSystemEvents.FILE_DELETED, { path: oldPath });\n          }\n          this.events.emit(FileSystemEvents.FILE_WRITTEN, { \n            path, \n            size: event.data.size || 0 \n          });\n          break;\n      }\n    };\n  }\n\n  private broadcastChange(event: FSEvent & { size?: number; isDirectory?: boolean; fileType?: \"file\" | \"directory\" }): void {\n    if (this.broadcastChannel) {\n      this.broadcastChannel.postMessage({\n        ...event,\n        timestamp: event.timestamp.toISOString(),\n      });\n    }\n  }\n\n  async startWatching(pollingIntervalMs: number = 250): Promise<void> {\n    if (!this.enableExternalSync) return;\n    \n    // Take initial snapshot\n    await this.updateFileSnapshots();\n    \n    // Start polling for changes\n    this.pollingInterval = setInterval(async () => {\n      await this.checkForExternalChanges();\n    }, pollingIntervalMs);\n  }\n\n  async stopWatching(): Promise<void> {\n    if (this.pollingInterval) {\n      clearInterval(this.pollingInterval);\n      this.pollingInterval = null;\n    }\n  }\n\n  private async updateFileSnapshots(): Promise<void> {\n    const db = await this.ensureDB();\n    \n    return new Promise((resolve, reject) => {\n      const transaction = db.transaction([this.config.storeName], \"readonly\");\n      const store = transaction.objectStore(this.config.storeName);\n      const request = store.getAll();\n      \n      request.onsuccess = async () => {\n        const files = request.result as StoredFile[];\n        this.fileSnapshots.clear();\n        \n        for (const file of files) {\n          // Include both files and directories in snapshots\n          if (file.path !== \"/\") { // Skip root directory\n            const snapshot: FileSnapshot = {\n              path: file.path,\n              type: file.type,\n              modified: file.modified,\n              size: file.size,\n            };\n            \n            // Calculate content hash if deep detection is enabled\n            if (this.deepChangeDetection && file.type === \"file\") {\n              snapshot.contentHash = await this.calculateHash(file.content);\n              if (file.metadata) {\n                snapshot.metadataHash = await this.calculateHash(file.metadata);\n              }\n            }\n            \n            this.fileSnapshots.set(file.path, snapshot);\n          }\n        }\n        \n        resolve();\n      };\n      \n      request.onerror = () => {\n        reject(new Error(`Failed to update snapshots: ${request.error}`));\n      };\n    });\n  }\n\n  private async checkForExternalChanges(): Promise<void> {\n    const db = await this.ensureDB();\n    const currentFiles = new Map<string, FileSnapshot>();\n    const filesToDeepCheck: string[] = [];\n    \n    return new Promise((resolve) => {\n      const transaction = db.transaction([this.config.storeName], \"readonly\");\n      const store = transaction.objectStore(this.config.storeName);\n      const request = store.getAll();\n      \n      request.onsuccess = async () => {\n        const files = request.result as StoredFile[];\n        \n        // Build current state map - include both files and directories\n        files.forEach(file => {\n          if (file.path !== \"/\") { // Skip root directory\n            currentFiles.set(file.path, {\n              path: file.path,\n              type: file.type,\n              modified: file.modified,\n              size: file.size,\n            });\n          }\n        });\n        \n        // Phase 1: Quick check (date/size)\n        currentFiles.forEach((current, path) => {\n          const snapshot = this.fileSnapshots.get(path);\n          \n          if (!snapshot) {\n            // New file or directory\n            this.notifyWatchers({\n              type: \"created\",\n              path,\n              timestamp: new Date(),\n            });\n            \n            // Also emit proper events\n            if (current.type === \"directory\") {\n              this.events.emit(FileSystemEvents.DIR_CREATED, { path });\n            } else {\n              this.events.emit(FileSystemEvents.FILE_WRITTEN, { path, size: current.size });\n            }\n          } else if (\n            current.modified.getTime() !== snapshot.modified.getTime() ||\n            current.size !== snapshot.size\n          ) {\n            // Modified file - detected by date/size\n            this.notifyWatchers({\n              type: \"updated\",\n              path,\n              timestamp: new Date(),\n            });\n            \n            if (current.type === \"file\") {\n              this.events.emit(FileSystemEvents.FILE_WRITTEN, { path, size: current.size });\n            }\n          } else if (this.deepChangeDetection && current.type === \"file\") {\n            // Mark for deep check\n            filesToDeepCheck.push(path);\n          }\n        });\n        \n        // Check for deleted files/directories\n        this.fileSnapshots.forEach((snapshot, path) => {\n          if (!currentFiles.has(path)) {\n            this.notifyWatchers({\n              type: \"deleted\",\n              path,\n              timestamp: new Date(),\n            });\n            \n            // Also emit proper events\n            if (snapshot.type === \"directory\") {\n              this.events.emit(FileSystemEvents.DIR_DELETED, { path });\n            } else {\n              this.events.emit(FileSystemEvents.FILE_DELETED, { path });\n            }\n          }\n        });\n        \n        // Phase 2: Deep check (content) - only if enabled and needed\n        if (filesToDeepCheck.length > 0) {\n          await this.performDeepContentCheck(filesToDeepCheck, files);\n        }\n        \n        // Update snapshots with content hashes if deep check is enabled\n        if (this.deepChangeDetection) {\n          for (const file of files) {\n            if (file.type === \"file\" && file.path !== \"/\") {\n              const snapshot = currentFiles.get(file.path);\n              if (snapshot) {\n                snapshot.contentHash = await this.calculateHash(file.content);\n                if (file.metadata) {\n                  snapshot.metadataHash = await this.calculateHash(file.metadata);\n                }\n              }\n            }\n          }\n        }\n        \n        // Update snapshots\n        this.fileSnapshots = currentFiles;\n        resolve();\n      };\n      \n      request.onerror = () => resolve();\n    });\n  }\n  \n  private async performDeepContentCheck(paths: string[], allFiles: StoredFile[]): Promise<void> {\n    for (const path of paths) {\n      const file = allFiles.find(f => f.path === path);\n      const snapshot = this.fileSnapshots.get(path);\n      \n      if (file && snapshot) {\n        const currentContentHash = await this.calculateHash(file.content);\n        const currentMetadataHash = file.metadata ? await this.calculateHash(file.metadata) : undefined;\n        \n        const contentChanged = snapshot.contentHash && snapshot.contentHash !== currentContentHash;\n        const metadataChanged = snapshot.metadataHash && currentMetadataHash && snapshot.metadataHash !== currentMetadataHash;\n        \n        if (contentChanged || metadataChanged) {\n          // Content or metadata changed even though date/size didn't\n          this.notifyWatchers({\n            type: \"updated\",\n            path,\n            timestamp: new Date(),\n          });\n          \n          this.events.emit(FileSystemEvents.FILE_WRITTEN, { \n            path, \n            size: file.size \n          });\n        }\n      }\n    }\n  }\n\n  dispose(): void {\n    this.stopWatching();\n    \n    if (this.broadcastChannel) {\n      this.broadcastChannel.close();\n      this.broadcastChannel = null;\n    }\n    \n    if (this.db) {\n      this.db.close();\n      this.db = null;\n    }\n    \n    this.watchers = [];\n    this.fileSnapshots.clear();\n  }\n\n  // Sobrescrever métodos de permissão (sempre permitido em IndexedDB)\n  async canModify(path: string): Promise<boolean> {\n    return true; // Sempre permitido em IndexedDB\n  }\n\n  async canCreateIn(parentPath: string): Promise<boolean> {\n    try {\n      const stat = await this.stat(parentPath);\n      return stat.type === \"directory\";\n    } catch {\n      // Se não existe, verifica se é o root\n      return normalizePath(parentPath) === \"/\";\n    }\n  }\n\n  // Não sobrescrever writeFileAtomic - usar implementação base\n  // IndexedDB não tem rename verdadeiramente atômico\n}\n"],"mappings":"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","names":["event"]}