{"version":3,"file":"portable-BDL1bEL6.mjs","names":["nodeFsPromises: FSPromises | null","nodeFsSync: FSSync | null","pathModule: { dirname: (path: string) => string } | null","pathModule","fsInstance: PortableFS | null","hasherInstance: PortableHasher | null"],"sources":["../src/portable/fs.ts","../src/portable/hash.ts","../src/portable/runtime.ts"],"sourcesContent":["/**\n * Portable filesystem API using Node.js fs\n */\n\nexport interface PortableFS {\n  readFile(path: string): Promise<string>;\n  writeFile(path: string, content: string): Promise<void>;\n  /**\n   * Write a file atomically using temp file + rename pattern.\n   * This prevents partial/corrupt writes on crash.\n   */\n  writeFileAtomic(path: string, content: string): Promise<void>;\n  exists(path: string): Promise<boolean>;\n  stat(path: string): Promise<{ mtime: Date; size: number }>;\n  rename(oldPath: string, newPath: string): Promise<void>;\n  mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n  /**\n   * Write a file synchronously and atomically using temp file + rename pattern.\n   * Safe for use in beforeExit handlers.\n   */\n  writeFileSyncAtomic(path: string, content: string): void;\n  /**\n   * Remove a file. Does not throw if file doesn't exist.\n   */\n  unlink(path: string): Promise<void>;\n  /**\n   * Remove a file synchronously. Does not throw if file doesn't exist.\n   */\n  unlinkSync(path: string): void;\n  /**\n   * Read a file synchronously.\n   */\n  readFileSync(path: string): string;\n}\n\ninterface FSPromises {\n  readFile: (path: string, encoding: string) => Promise<string>;\n  writeFile: (path: string, content: string, encoding: string) => Promise<void>;\n  access: (path: string) => Promise<void>;\n  stat: (path: string) => Promise<{\n    mtime: Date;\n    size: number;\n    isDirectory: () => boolean;\n  }>;\n  rename: (oldPath: string, newPath: string) => Promise<void>;\n  mkdir: (path: string, options?: { recursive?: boolean }) => Promise<void>;\n  unlink: (path: string) => Promise<void>;\n}\n\ninterface FSSync {\n  writeFileSync: (path: string, content: string, encoding: string) => void;\n  renameSync: (oldPath: string, newPath: string) => void;\n  unlinkSync: (path: string) => void;\n  readFileSync: (path: string, encoding: string) => string;\n  mkdirSync: (path: string, options?: { recursive?: boolean }) => void;\n}\n\n// Cache the fs/promises import\nlet nodeFsPromises: FSPromises | null = null;\nconst getNodeFS = async (): Promise<FSPromises> => {\n  if (!nodeFsPromises) {\n    const fs = await import(\"node:fs/promises\");\n    nodeFsPromises = fs as FSPromises;\n  }\n  return nodeFsPromises;\n};\n\n// Cache the sync fs import\nlet nodeFsSync: FSSync | null = null;\nconst getNodeFSSync = (): FSSync => {\n  if (!nodeFsSync) {\n    // Use require for sync loading\n    // eslint-disable-next-line @typescript-eslint/no-require-imports\n    nodeFsSync = require(\"node:fs\") as FSSync;\n  }\n  return nodeFsSync;\n};\n\n// Cache path module\nlet pathModule: { dirname: (path: string) => string } | null = null;\nconst getPathModule = (): { dirname: (path: string) => string } => {\n  if (!pathModule) {\n    // eslint-disable-next-line @typescript-eslint/no-require-imports\n    pathModule = require(\"node:path\") as { dirname: (path: string) => string };\n  }\n  return pathModule;\n};\n\n/**\n * Generate a unique temp file path for atomic write.\n */\nconst getTempPath = (targetPath: string): string => {\n  return `${targetPath}.${process.pid}.${Date.now()}.tmp`;\n};\n\nexport function createPortableFS(): PortableFS {\n  return {\n    async readFile(path) {\n      const nodeFS = await getNodeFS();\n      return await nodeFS.readFile(path, \"utf-8\");\n    },\n\n    async writeFile(path, content) {\n      const nodeFS = await getNodeFS();\n      // Auto-create parent directories like Bun.write does\n      const pathModule = await import(\"node:path\");\n      const dir = pathModule.dirname(path);\n      await nodeFS.mkdir(dir, { recursive: true });\n      await nodeFS.writeFile(path, content, \"utf-8\");\n    },\n\n    async writeFileAtomic(path, content) {\n      const nodeFS = await getNodeFS();\n      const pathMod = await import(\"node:path\");\n      const dir = pathMod.dirname(path);\n      const tempPath = getTempPath(path);\n\n      try {\n        await nodeFS.mkdir(dir, { recursive: true });\n        await nodeFS.writeFile(tempPath, content, \"utf-8\");\n        await nodeFS.rename(tempPath, path);\n      } catch (error) {\n        // Clean up temp file on failure\n        try {\n          await nodeFS.unlink(tempPath);\n        } catch {\n          // Ignore cleanup errors\n        }\n        throw error;\n      }\n    },\n\n    async exists(path) {\n      const nodeFS = await getNodeFS();\n      try {\n        await nodeFS.access(path);\n        return true;\n      } catch {\n        return false;\n      }\n    },\n\n    async stat(path) {\n      const nodeFS = await getNodeFS();\n      const stats = await nodeFS.stat(path);\n      return { mtime: stats.mtime, size: stats.size };\n    },\n\n    async rename(oldPath, newPath) {\n      const nodeFS = await getNodeFS();\n      await nodeFS.rename(oldPath, newPath);\n    },\n\n    async mkdir(path, options) {\n      const nodeFS = await getNodeFS();\n      await nodeFS.mkdir(path, options);\n    },\n\n    writeFileSyncAtomic(path, content) {\n      const fsSync = getNodeFSSync();\n      const pathMod = getPathModule();\n      const tempPath = getTempPath(path);\n\n      // Ensure parent directory exists\n      const dir = pathMod.dirname(path);\n      fsSync.mkdirSync(dir, { recursive: true });\n\n      try {\n        fsSync.writeFileSync(tempPath, content, \"utf-8\");\n        fsSync.renameSync(tempPath, path);\n      } catch (error) {\n        // Clean up temp file on failure\n        try {\n          fsSync.unlinkSync(tempPath);\n        } catch {\n          // Ignore cleanup errors\n        }\n        throw error;\n      }\n    },\n\n    async unlink(path) {\n      const nodeFS = await getNodeFS();\n      try {\n        await nodeFS.unlink(path);\n      } catch (error) {\n        // Ignore ENOENT (file not found)\n        if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n          throw error;\n        }\n      }\n    },\n\n    unlinkSync(path) {\n      const fsSync = getNodeFSSync();\n      try {\n        fsSync.unlinkSync(path);\n      } catch (error) {\n        // Ignore ENOENT (file not found)\n        if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n          throw error;\n        }\n      }\n    },\n\n    readFileSync(path) {\n      const fsSync = getNodeFSSync();\n      return fsSync.readFileSync(path, \"utf-8\");\n    },\n  };\n}\n\n// Singleton to avoid recreating instances\nlet fsInstance: PortableFS | null = null;\n\nexport function getPortableFS(): PortableFS {\n  if (!fsInstance) {\n    fsInstance = createPortableFS();\n  }\n  return fsInstance;\n}\n\n/**\n * Reset the filesystem singleton for testing\n * @internal\n */\nexport function __resetPortableFSForTests(): void {\n  fsInstance = null;\n}\n","/**\n * Portable hashing API using Node.js crypto\n */\n\nimport { createHash } from \"node:crypto\";\n\nexport type HashAlgorithm = \"sha256\" | \"xxhash\";\n\nexport interface PortableHasher {\n  hash(content: string, algorithm?: HashAlgorithm): string;\n}\n\nexport function createPortableHasher(): PortableHasher {\n  return {\n    hash(content, algorithm = \"xxhash\") {\n      if (algorithm === \"sha256\") {\n        return createHash(\"sha256\").update(content).digest(\"hex\");\n      }\n      // xxhash fallback: use sha256 truncated to 16 chars\n      const sha256Hash = createHash(\"sha256\").update(content).digest(\"hex\");\n      return sha256Hash.substring(0, 16);\n    },\n  };\n}\n\n// Singleton to avoid recreating instances\nlet hasherInstance: PortableHasher | null = null;\n\nexport function getPortableHasher(): PortableHasher {\n  if (!hasherInstance) {\n    hasherInstance = createPortableHasher();\n  }\n  return hasherInstance;\n}\n\n/**\n * Reset the hasher singleton for testing\n * @internal\n */\nexport function __resetPortableHasherForTests(): void {\n  hasherInstance = null;\n}\n","/**\n * Runtime detection utilities for portable API implementation\n * Note: Bun-specific code has been removed. Node.js APIs are always used.\n */\n\nexport const runtime = {\n  isBun: false,\n  isNode: typeof process !== \"undefined\",\n  supportsWebCrypto: typeof crypto !== \"undefined\" && typeof crypto.subtle !== \"undefined\",\n} as const;\n\n/**\n * Reset runtime state for testing purposes only\n * @internal\n */\nexport function resetPortableForTests(): void {\n  // This is a marker function that portable modules can use\n  // to reset their singleton state in tests\n}\n"],"mappings":"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"}