{"version":3,"file":"async.mjs","names":[],"sources":["../src/async/internal/helpers.ts","../src/async/core/create.ts","../src/async/core/read.ts","../src/async/core/remove.ts","../src/async/core/stat.ts","../src/async/core/truncate.ts","../src/async/core/write.ts","../src/async/ext.ts","../src/async/archive/helpers.ts","../src/async/archive/unzip-stream.ts","../src/async/archive/unzip.ts","../src/async/archive/zip-stream.ts","../src/async/archive/zip.ts","../src/async/tmp.ts","../src/async/transfer/download.ts","../src/async/transfer/upload.ts"],"sourcesContent":["/**\n * Internal helper utilities for async file operations.\n * These functions are not exported publicly.\n *\n * @internal\n * @module\n */\n\nimport type { FetchTask } from '@happy-ts/fetch-t';\nimport { basename, dirname, SEPARATOR } from '@std/path/posix';\nimport { LazyAsync, Ok, RESULT_VOID, tryAsyncResult, type AsyncIOResult, type AsyncVoidIOResult, type IOResult } from 'happy-rusty';\nimport { ABORT_ERROR, EMPTY_BODY_ERROR, EMPTY_FILE_ERROR, NOT_FOUND_ERROR, NOTHING_TO_ZIP_ERROR, ROOT_DIR } from '../../shared/mod.ts';\n\n// #region Internal Variables\n\n/**\n * Lazily initialized root directory handle of the file system.\n * Created on first access via `force()`.\n */\nconst fsRoot = /*#__PURE__*/ LazyAsync(() => navigator.storage.getDirectory());\n\n// #endregion\n\n/**\n * Checks if the provided path is the root directory path.\n *\n * @param path - The path to check.\n * @returns `true` if the path equals `'/'`, otherwise `false`.\n */\nexport function isRootDir(path: string): boolean {\n    return path === ROOT_DIR;\n}\n\n/**\n * Retrieves a directory handle by traversing the path from root.\n *\n * Algorithm:\n * 1. Start from the OPFS root directory\n * 2. If path is `/`, return root immediately\n * 3. Split path by `/` separator and iterate through each segment\n * 4. For each segment, get or create the child directory handle\n * 5. Return error immediately if any segment fails\n *\n * @param dirPath - The absolute path of the directory to retrieve.\n * @param options - Optional parameters (e.g., `{ create: true }` to create intermediate directories).\n * @returns A promise that resolves to an `AsyncIOResult` containing the `FileSystemDirectoryHandle`.\n */\nexport async function getDirHandle(dirPath: string, options?: FileSystemGetDirectoryOptions): AsyncIOResult<FileSystemDirectoryHandle> {\n    // Start from root\n    let dirHandle = fsRoot.isInitialized()\n        ? fsRoot.get().unwrap()\n        : await fsRoot.force();\n\n    if (isRootDir(dirPath)) {\n        // Root is already a handle, no traversal needed\n        return Ok(dirHandle);\n    } else {\n        // NOTE: Empty else branch is intentional to fix V8 coverage tracking.\n        // Without explicit else, V8 incorrectly marks code after early return as uncovered.\n    }\n\n    // Traverse path from root\n    // Iterate through each path segment\n    // Path is already normalized by validateAbsolutePath, no empty segments\n    // Remove leading '/' and start traversing\n    for (const childDirName of dirPath.slice(1).split(SEPARATOR)) {\n        // Get or create child directory\n        const dirHandleRes = await getChildDirHandle(dirHandle, childDirName, options);\n        if (dirHandleRes.isErr()) {\n            // Stop traversal on error\n            return dirHandleRes;\n        }\n\n        dirHandle = dirHandleRes.unwrap();\n    }\n\n    return Ok(dirHandle);\n}\n\n/**\n * Gets the directory handle for the parent directory of the given path.\n *\n * @param path - The absolute path whose parent directory handle is to be retrieved.\n * @param options - Optional parameters (e.g., `{ create: true }` to create intermediate directories).\n * @returns A promise that resolves to an `AsyncIOResult` containing the parent `FileSystemDirectoryHandle`.\n */\nexport function getParentDirHandle(path: string, options?: FileSystemGetDirectoryOptions): AsyncIOResult<FileSystemDirectoryHandle> {\n    return getDirHandle(dirname(path), options);\n}\n\n/**\n * Retrieves a file handle given a file path.\n *\n * @param filePath - The absolute path of the file to retrieve.\n * @param options - Optional parameters (e.g., `{ create: true }` to create the file if not exists).\n * @returns A promise that resolves to an `AsyncIOResult` containing the `FileSystemFileHandle`.\n */\nexport async function getFileHandle(filePath: string, options?: FileSystemGetFileOptions): AsyncIOResult<FileSystemFileHandle> {\n    const dirHandleRes = await getParentDirHandle(filePath, options);\n\n    return dirHandleRes.andThenAsync(dirHandle => {\n        const fileName = basename(filePath);\n        return getChildFileHandle(dirHandle, fileName, options);\n    });\n}\n\n/**\n * Checks whether the error is a `NotFoundError`.\n *\n * @param err - The error to check.\n * @returns `true` if the error's name is `'NotFoundError'`, otherwise `false`.\n */\nexport function isNotFoundError(err: Error): boolean {\n    return err.name === NOT_FOUND_ERROR;\n}\n\n/**\n * Aggregates multiple async void I/O results into a single result.\n * Waits for all tasks to complete, then returns the first error encountered,\n * or a void success result if all tasks succeed.\n *\n * @param tasks - The list of async void I/O result promises to aggregate.\n * @returns A promise that resolves to the first error result, or `RESULT_VOID` if all tasks succeed.\n */\nexport async function aggregateResults(tasks: AsyncVoidIOResult[]): AsyncVoidIOResult {\n    if (tasks.length === 0) {\n        return RESULT_VOID;\n    }\n\n    const allRes = await Promise.all(tasks);\n    return allRes.find(x => x.isErr()) ?? RESULT_VOID;\n}\n\n/**\n * Creates an `AbortError` instance.\n * Used to signal that an operation was aborted.\n *\n * @returns An `Error` object with the name set to `'AbortError'`.\n */\nexport function createAbortError(): Error {\n    const error = new Error('Operation was aborted');\n    error.name = ABORT_ERROR;\n\n    return error;\n}\n\n/**\n * Creates an `EmptyBodyError` instance.\n * Used to signal that a response body is empty (null).\n *\n * @returns An `Error` object with the name set to `'EmptyBodyError'`.\n */\nexport function createEmptyBodyError(): Error {\n    const error = new Error('Response body is empty');\n    error.name = EMPTY_BODY_ERROR;\n\n    return error;\n}\n\n/**\n * Creates an `EmptyFileError` instance.\n * Used to signal that a file content is empty (0 bytes).\n *\n * @returns An `Error` object with the name set to `'EmptyFileError'`.\n */\nexport function createEmptyFileError(): Error {\n    const error = new Error('File content is empty');\n    error.name = EMPTY_FILE_ERROR;\n\n    return error;\n}\n\n/**\n * Creates a `NothingToZipError` instance.\n * Used when attempting to zip an empty directory with preserveRoot=false.\n *\n * @returns An `Error` object with the name set to `'NothingToZipError'`.\n */\nexport function createNothingToZipError(): Error {\n    const error = new Error('Nothing to zip');\n    error.name = NOTHING_TO_ZIP_ERROR;\n\n    return error;\n}\n\n/**\n * Creates a failed FetchTask that immediately resolves with an error.\n * Used when validation fails before making the actual fetch request.\n *\n * @param errResult - The error result to return.\n * @returns A FetchTask that resolves with the error.\n */\nexport function createFailedFetchTask<T>(errResult: IOResult<unknown>): FetchTask<T> {\n    return {\n        abort(): void { /* noop */ },\n        get aborted(): boolean { return false; },\n        get result() { return Promise.resolve(errResult.asErr<T>()); },\n    };\n}\n\n/**\n * Marks all parent directories of a path as non-empty.\n * Used to optimize directory creation by skipping directories that will be\n * implicitly created when writing files.\n *\n * @param path - The relative file path.\n * @param nonEmptyDirs - Set to track non-empty directories.\n */\nexport function markParentDirsNonEmpty(\n    path: string,\n    nonEmptyDirs: Set<string>,\n): void {\n    let slashIndex = path.lastIndexOf(SEPARATOR);\n    while (slashIndex > 0) {\n        const parent = path.slice(0, slashIndex);\n        if (nonEmptyDirs.has(parent)) break;\n        nonEmptyDirs.add(parent);\n        slashIndex = path.lastIndexOf(SEPARATOR, slashIndex - 1);\n    }\n}\n\n/**\n * Removes a file or directory with cross-browser compatibility.\n * Accepts either a handle or a name string. When a handle is provided and\n * `handle.remove()` is supported (Chrome/Edge), uses native removal.\n * Otherwise falls back to `parentDirHandle.removeEntry()`.\n *\n * For root directory removal on Firefox/Safari (where `handle.remove()` is not supported),\n * iterates through all children and removes them individually.\n *\n * @param handleOrName - The handle to remove, or the name of the entry.\n * @param parentDirHandle - The parent directory handle.\n * @param options - Optional remove options (e.g., `{ recursive: true }`).\n * @returns A promise that resolves when the entry is removed.\n */\nexport async function removeHandle(\n    handleOrName: FileSystemHandle | string,\n    parentDirHandle: FileSystemDirectoryHandle,\n    options?: FileSystemRemoveOptions,\n): Promise<void> {\n    if (typeof handleOrName === 'string') {\n        // Name string: use removeEntry directly\n        return parentDirHandle.removeEntry(handleOrName, options);\n    }\n\n    const removableHandle = handleOrName as RemovableHandle;\n\n    if (typeof removableHandle.remove === 'function') {\n        // Chrome/Edge: use native handle.remove()\n        return removableHandle.remove(options);\n    }\n\n    // Firefox/Safari: fallback to removeEntry()\n    // Special case: root directory has empty name, cannot use removeEntry\n    // Instead, iterate and remove all children\n    if (!handleOrName.name) {\n        const dirHandle = handleOrName as FileSystemDirectoryHandle;\n        const tasks: Promise<void>[] = [];\n\n        for await (const childName of dirHandle.keys()) {\n            tasks.push(dirHandle.removeEntry(childName, options));\n        }\n\n        if (tasks.length > 0) {\n            await Promise.all(tasks);\n        }\n    } else {\n        return parentDirHandle.removeEntry(handleOrName.name, options);\n    }\n}\n\n/**\n * Result of peeking a stream's first chunk.\n */\nexport interface PeekStreamResult<T> {\n    /** Whether the stream is empty (no data). */\n    isEmpty: boolean;\n    /** The reconstructed stream with first chunk prepended. Only valid if not empty. */\n    stream: ReadableStream<T>;\n}\n\n/**\n * Peeks the first chunk of a ReadableStream to check if it's empty.\n * Returns the original stream reconstructed with the peeked chunk prepended.\n *\n * This enables true streaming while detecting empty streams before processing.\n *\n * @param source - The source ReadableStream to peek.\n * @returns A promise resolving to an `AsyncIOResult` containing PeekStreamResult with isEmpty flag and reconstructed stream.\n */\nexport async function peekStream<T>(source: ReadableStream<T>): AsyncIOResult<PeekStreamResult<T>> {\n    const reader = source.getReader();\n\n    const firstRes = await tryAsyncResult(reader.read());\n    if (firstRes.isErr()) {\n        reader.releaseLock();\n        return firstRes.asErr();\n    }\n\n    const first = firstRes.unwrap();\n\n    if (first.done) {\n        reader.releaseLock();\n        // Return a new empty stream since the original is already consumed\n        return Ok({\n            isEmpty: true,\n            stream: new ReadableStream<T>({\n                start(controller) {\n                    controller.close();\n                },\n            }),\n        });\n    }\n\n    // Reconstruct stream: first chunk + remaining data\n    const stream = new ReadableStream<T>({\n        async start(controller) {\n            controller.enqueue(first.value);\n        },\n        async pull(controller) {\n            try {\n                const { done, value } = await reader.read();\n                if (done) {\n                    reader.releaseLock();\n                    controller.close();\n                } else {\n                    controller.enqueue(value);\n                }\n            } catch (err) {\n                reader.releaseLock();\n                controller.error(err);\n            }\n        },\n        async cancel(reason) {\n            try {\n                await reader.cancel(reason);\n            } finally {\n                reader.releaseLock();\n            }\n        },\n    });\n\n    return Ok({\n        isEmpty: false,\n        stream,\n    });\n}\n\n/**\n * Moves a file handle to a new path, creating parent directories if needed.\n *\n * Uses the native `move()` when available (instant rename; supported by all\n * modern browsers — Chrome 102+, Firefox 111+, Safari 15.2+ — though not on\n * the standards track). Falls back to copy semantics for older browsers without\n * `move()` — the caller is responsible for removing the source path after a\n * successful move.\n *\n * @param fileHandle - The file handle to move.\n * @param destFilePath - The destination absolute file path.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n */\nexport async function moveFileHandle(fileHandle: FileSystemFileHandle, destFilePath: string): AsyncVoidIOResult {\n    const dirRes = await getParentDirHandle(destFilePath, {\n        create: true,\n    });\n\n    return dirRes.andTryAsync(async destDirHandle => {\n        const destName = basename(destFilePath);\n        const movable = fileHandle as unknown as MovableHandle;\n\n        // Native move (instant rename) when supported\n        if (typeof movable.move === 'function') {\n            return movable.move(destDirHandle, destName);\n        }\n\n        // Fallback: copy file content to dest (older browsers without handle.move())\n        // Inlined to avoid circular dep on write.ts (write.ts imports this module)\n        // getFile() and dest writable acquisition are independent — run in parallel\n        const [file, writable] = await Promise.all([\n            fileHandle.getFile(),\n            destDirHandle.getFileHandle(destName, { create: true })\n                .then(handle => handle.createWritable()),\n        ]);\n        try {\n            await writable.write(file);\n        } finally {\n            await writable.close();\n        }\n    });\n}\n\n// #region Internal Types\n\n/**\n * Extended FileSystemHandle interface with optional remove method.\n * The remove() method is not supported in Firefox/iOS Safari.\n */\ninterface RemovableHandle extends FileSystemHandle {\n    remove?(options?: FileSystemRemoveOptions): Promise<void>;\n}\n\n/**\n * Extended FileSystemHandle interface with move method.\n * The move() method is not yet in TypeScript's lib.dom.d.ts.\n * @see https://github.com/mdn/browser-compat-data/issues/20341\n */\ninterface MovableHandle extends FileSystemHandle {\n    move(destination: FileSystemDirectoryHandle, name: string): Promise<void>;\n}\n\n// #endregion\n\n// #region Internal Functions\n\n/**\n * Asynchronously obtains a handle to a child directory from the given parent directory handle.\n *\n * @param dirHandle - The handle to the parent directory.\n * @param childDirName - The name of the child directory to retrieve.\n * @param options - Optional parameters (e.g., `{ create: true }` to create if not exists).\n * @returns A promise that resolves to an `AsyncIOResult` containing the `FileSystemDirectoryHandle`.\n */\nasync function getChildDirHandle(dirHandle: FileSystemDirectoryHandle, childDirName: string, options?: FileSystemGetDirectoryOptions): AsyncIOResult<FileSystemDirectoryHandle> {\n    const handleRes = await tryAsyncResult<FileSystemDirectoryHandle, DOMException>(dirHandle.getDirectoryHandle(childDirName, options));\n    return handleRes.mapErr(err => {\n        const error = new Error(`${ err.name }: ${ err.message } When get child directory '${ childDirName }' from directory '${ dirHandle.name || ROOT_DIR }'`);\n        error.name = err.name;\n        return error;\n    });\n}\n\n/**\n * Retrieves a file handle for a child file within a directory.\n *\n * @param dirHandle - The directory handle to search within.\n * @param childFileName - The name of the file to retrieve.\n * @param options - Optional parameters (e.g., `{ create: true }` to create if not exists).\n * @returns A promise that resolves to an `AsyncIOResult` containing the `FileSystemFileHandle`.\n */\nasync function getChildFileHandle(dirHandle: FileSystemDirectoryHandle, childFileName: string, options?: FileSystemGetFileOptions): AsyncIOResult<FileSystemFileHandle> {\n    const handleRes = await tryAsyncResult<FileSystemFileHandle, DOMException>(dirHandle.getFileHandle(childFileName, options));\n    return handleRes.mapErr(err => {\n        const error = new Error(`${ err.name }: ${ err.message } When get child file '${ childFileName }' from directory '${ dirHandle.name || ROOT_DIR }'`);\n        error.name = err.name;\n        return error;\n    });\n}\n\n// #endregion\n","import { RESULT_VOID, type AsyncVoidIOResult } from 'happy-rusty';\nimport { validateAbsolutePath } from '../../shared/internal/mod.ts';\nimport { getDirHandle, getFileHandle } from '../internal/mod.ts';\n\n/**\n * Creates a new empty file at the specified path, similar to the `touch` command.\n * If the file already exists, this operation succeeds without modifying it.\n * Parent directories are created automatically if they don't exist.\n *\n * **Note:** For temporary files, use {@link mkTemp} instead, which provides\n * automatic unique naming and integrates with {@link pruneTemp} for cleanup.\n *\n * @param filePath - The absolute path of the file to create.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 1.7.0\n * @see {@link createFileSync} for synchronous version\n * @see {@link mkTemp} for creating temporary files\n * @see {@link writeFile} for creating files with content\n * @example\n * ```typescript\n * (await createFile('/path/to/file.txt'))\n *     .inspect(() => console.log('File created'));\n * ```\n */\nexport async function createFile(filePath: string): AsyncVoidIOResult {\n    const filePathRes = validateAbsolutePath(filePath);\n    if (filePathRes.isErr()) return filePathRes.asErr();\n    filePath = filePathRes.unwrap();\n\n    const handleRes = await getFileHandle(filePath, {\n        create: true,\n    });\n\n    return handleRes.and(RESULT_VOID);\n}\n\n/**\n * Creates a new directory at the specified path, similar to `mkdir -p`.\n * Creates all necessary parent directories if they don't exist.\n *\n * **Note:** For temporary directories, use {@link mkTemp} with `{ isDirectory: true }` instead,\n * which provides automatic unique naming and integrates with temporary file management.\n *\n * @param dirPath - The absolute path where the directory will be created.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 1.0.0\n * @see {@link mkdirSync} for synchronous version\n * @see {@link emptyDir} for creating or emptying a directory\n * @see {@link mkTemp} for creating temporary directories\n * @example\n * ```typescript\n * (await mkdir('/path/to/new/directory'))\n *     .inspect(() => console.log('Directory created'));\n * ```\n */\nexport async function mkdir(dirPath: string): AsyncVoidIOResult {\n    const dirPathRes = validateAbsolutePath(dirPath);\n    if (dirPathRes.isErr()) return dirPathRes.asErr();\n    dirPath = dirPathRes.unwrap();\n\n    const handleRes = await getDirHandle(dirPath, {\n        create: true,\n    });\n\n    return handleRes.and(RESULT_VOID);\n}\n","import { join } from '@std/path/posix';\nimport { Err, Ok, type AsyncIOResult } from 'happy-rusty';\nimport { decodeUtf8, readBlobBytes, validateAbsolutePath } from '../../shared/internal/mod.ts';\nimport { isDirectoryHandle, type DirEntry, type ReadDirOptions, type ReadFileContent, type ReadOptions } from '../../shared/mod.ts';\nimport { createAbortError, getDirHandle, getFileHandle } from '../internal/mod.ts';\n/**\n * Reads the contents of a directory at the specified path.\n *\n * @param dirPath - The path of the directory to read.\n * @param options - Options of readdir.\n * @returns A promise that resolves to an `AsyncIOResult` containing an async iterable iterator over the entries of the directory.\n * @since 1.0.0\n * @see {@link readDirSync} for synchronous version\n * @example\n * ```typescript\n * // List directory contents\n * (await readDir('/documents'))\n *     .inspect(async entries => {\n *         for await (const entry of entries) {\n *             console.log(entry.path, entry.handle.kind);\n *         }\n *     });\n *\n * // List recursively\n * await readDir('/documents', { recursive: true });\n * ```\n */\nexport async function readDir(dirPath: string, options?: ReadDirOptions): AsyncIOResult<AsyncIterableIterator<DirEntry>> {\n    const dirPathRes = validateAbsolutePath(dirPath);\n    if (dirPathRes.isErr()) return dirPathRes.asErr();\n    dirPath = dirPathRes.unwrap();\n\n    const dirHandleRes = await getDirHandle(dirPath);\n    if (dirHandleRes.isErr()) {\n        return dirHandleRes.asErr();\n    }\n\n    // Check if aborted after getting handle\n    if (options?.signal?.aborted) {\n        const { reason } = options.signal;\n        return Err(reason instanceof Error ? reason : createAbortError());\n    }\n\n    async function* read(dirHandle: FileSystemDirectoryHandle, relativePath?: string): AsyncIterableIterator<DirEntry> {\n        if (options?.signal?.aborted) {\n            return;\n        }\n\n        for await (const [name, handle] of dirHandle.entries()) {\n            // Check if aborted before yielding each entry\n            if (options?.signal?.aborted) {\n                return;\n            }\n\n            const path = relativePath ? join(relativePath, name) : name;\n            yield {\n                path,\n                handle,\n            };\n\n            if (options?.recursive && isDirectoryHandle(handle)) {\n                yield* read(handle, path);\n            }\n        }\n    }\n\n    return Ok(read(dirHandleRes.unwrap()));\n}\n\n/**\n * Reads the content of a file at the specified path as a File.\n *\n * @param filePath - The path of the file to read.\n * @param options - Read options specifying the 'blob' encoding.\n * @returns A promise that resolves to an `AsyncIOResult` containing the file content as a File.\n * @since 1.0.0\n * @see {@link readFileSync} for synchronous version\n * @see {@link readBlobFile} convenience wrapper\n * @example\n * ```typescript\n * (await readFile('/path/to/file.txt', { encoding: 'blob' }))\n *     .inspect(file => console.log(file.name, file.size, file.type));\n * ```\n */\nexport function readFile(filePath: string, options: ReadOptions & {\n    encoding: 'blob';\n}): AsyncIOResult<File>;\n\n/**\n * Reads the content of a file at the specified path as a string.\n *\n * @param filePath - The path of the file to read.\n * @param options - Read options specifying the 'utf8' encoding.\n * @returns A promise that resolves to an `AsyncIOResult` containing the file content as a string.\n * @since 1.0.0\n * @see {@link readFileSync} for synchronous version\n * @see {@link readTextFile} convenience wrapper\n * @example\n * ```typescript\n * (await readFile('/path/to/file.txt', { encoding: 'utf8' }))\n *     .inspect(content => console.log(content));\n * ```\n */\nexport function readFile(filePath: string, options: ReadOptions & {\n    encoding: 'utf8';\n}): AsyncIOResult<string>;\n\n/**\n * Reads the content of a file at the specified path as a readable stream.\n * Useful for processing large files without loading them entirely into memory.\n *\n * @param filePath - The path of the file to read.\n * @param options - Read options specifying the 'stream' encoding.\n * @returns A promise that resolves to an `AsyncIOResult` containing a `ReadableStream<Uint8Array>`.\n * @since 1.0.0\n * @see {@link readFileSync} for synchronous version (bytes only)\n * @example\n * ```typescript\n * (await readFile('/path/to/large-file.bin', { encoding: 'stream' }))\n *     .inspect(async stream => {\n *         const reader = stream.getReader();\n *         while (true) {\n *             const { done, value } = await reader.read();\n *             if (done) break;\n *             console.log('Received chunk:', value.length, 'bytes');\n *         }\n *     });\n * ```\n */\nexport function readFile(filePath: string, options: ReadOptions & {\n    encoding: 'stream';\n}): AsyncIOResult<ReadableStream<Uint8Array<ArrayBuffer>>>;\n\n/**\n * Reads the content of a file at the specified path as a Uint8Array (default).\n *\n * @param filePath - The path of the file to read.\n * @param options - Optional read options. Defaults to 'bytes' encoding.\n * @returns A promise that resolves to an `AsyncIOResult` containing the file content as a Uint8Array.\n * @since 1.0.0\n * @see {@link readFileSync} for synchronous version\n * @example\n * ```typescript\n * (await readFile('/path/to/file.bin'))\n *     .inspect(bytes => console.log('First byte:', bytes[0]));\n * ```\n */\nexport function readFile(filePath: string, options?: ReadOptions & {\n    encoding?: 'bytes';\n}): AsyncIOResult<Uint8Array<ArrayBuffer>>;\n\n/**\n * Reads the content of a file at the specified path with the specified options.\n * This overload accepts any ReadOptions and returns the union of all possible content types.\n * Useful when the encoding is determined at runtime.\n *\n * @param filePath - The path of the file to read.\n * @param options - Optional read options.\n * @returns A promise that resolves to an `AsyncIOResult` containing the file content.\n * @since 1.0.0\n * @see {@link readFileSync} for synchronous version\n * @example\n * ```typescript\n * // When encoding is dynamic\n * const encoding = getUserPreference(); // 'utf8' | 'bytes' | ...\n * (await readFile('/path/to/file.txt', { encoding }))\n *     .inspect(content => {\n *         // content type is ReadFileContent (union type)\n *         if (typeof content === 'string') {\n *             console.log('Text:', content);\n *         } else if (content instanceof Uint8Array) {\n *             console.log('Bytes:', content.length);\n *         }\n *     });\n * ```\n */\nexport function readFile(filePath: string, options?: ReadOptions): AsyncIOResult<ReadFileContent>;\n\n/**\n * Reads the content of a file at the specified path with the specified options.\n *\n * @template T The type of the content to read from the file.\n * @param filePath - The path of the file to read.\n * @param options - Optional read options.\n * @returns A promise that resolves to an `AsyncIOResult` containing the file content.\n */\nexport async function readFile(filePath: string, options?: ReadOptions): AsyncIOResult<ReadFileContent> {\n    const filePathRes = validateAbsolutePath(filePath);\n    if (filePathRes.isErr()) return filePathRes.asErr();\n    filePath = filePathRes.unwrap();\n\n    const fileHandleRes = await getFileHandle(filePath);\n\n    return fileHandleRes.andTryAsync(async fileHandle => {\n        const encoding = options?.encoding;\n\n        // Prefer sync access in Worker for better performance\n        // Only for encodings that don't require File object or streaming\n        return encoding !== 'blob' && encoding !== 'stream' && typeof fileHandle.createSyncAccessHandle === 'function'\n            ? readViaSyncAccess(fileHandle, encoding)\n            // Main thread fallback or blob/stream encoding\n            : readViaFile(fileHandle, encoding);\n    });\n}\n\n/**\n * Reads file content using the Worker's FileSystemSyncAccessHandle API.\n * More performant than File-based reading in Worker context.\n */\nasync function readViaSyncAccess(\n    fileHandle: FileSystemFileHandle,\n    encoding?: 'bytes' | 'utf8',\n): Promise<Uint8Array<ArrayBuffer> | string> {\n    const accessHandle = await fileHandle.createSyncAccessHandle();\n\n    try {\n        const size = accessHandle.getSize();\n        const bytes = new Uint8Array(size);\n        accessHandle.read(bytes, { at: 0 });\n\n        if (encoding === 'utf8') {\n            return decodeUtf8(bytes);\n        }\n        // 'bytes' or undefined (default)\n        return bytes;\n    } finally {\n        accessHandle.close();\n    }\n}\n\n/**\n * Reads file content using the File API (main thread strategy).\n */\nasync function readViaFile(\n    fileHandle: FileSystemFileHandle,\n    encoding?: 'bytes' | 'utf8' | 'blob' | 'stream',\n): Promise<ReadFileContent> {\n    const file = await fileHandle.getFile();\n\n    switch (encoding) {\n        case 'blob': {\n            return file;\n        }\n        case 'utf8': {\n            return file.text();\n        }\n        case 'stream': {\n            return file.stream();\n        }\n        default: {\n            // 'bytes' or undefined (default)\n            return readBlobBytes(file);\n        }\n    }\n}\n","import { basename } from '@std/path/posix';\nimport { Err, RESULT_VOID, type AsyncVoidIOResult } from 'happy-rusty';\nimport { validateAbsolutePath } from '../../shared/internal/mod.ts';\nimport { getParentDirHandle, isNotFoundError, isRootDir, removeHandle } from '../internal/mod.ts';\n\n/**\n * Removes a file or directory at the specified path, similar to `rm -rf`.\n * If the path doesn't exist, the operation succeeds silently.\n *\n * @param path - The absolute path of the file or directory to remove.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 1.0.0\n * @see {@link removeSync} for synchronous version\n * @see {@link emptyDir} for emptying a directory without removing it\n * @see {@link deleteTemp} for removing the temporary directory\n * @example\n * ```typescript\n * (await remove('/path/to/file-or-directory'))\n *     .inspect(() => console.log('Removed successfully'));\n * ```\n */\nexport async function remove(path: string): AsyncVoidIOResult {\n    const pathRes = validateAbsolutePath(path);\n    if (pathRes.isErr()) return pathRes.asErr();\n    path = pathRes.unwrap();\n\n    const parentDirHandleRes = await getParentDirHandle(path);\n\n    const removeRes = await parentDirHandleRes.andTryAsync(parentDirHandle => {\n        // For root, parentDirHandle is the root itself\n        // For non-root, use basename as the entry name\n        const handleOrName = isRootDir(path) ? parentDirHandle : basename(path);\n        return removeHandle(handleOrName, parentDirHandle, {\n            recursive: true,\n        });\n    });\n\n    return removeRes.orElse(err => {\n        // not found as success\n        return isNotFoundError(err) ? RESULT_VOID : Err(err);\n    });\n}\n","import { basename } from '@std/path/posix';\nimport { tryAsyncResult, type AsyncIOResult } from 'happy-rusty';\nimport { validateAbsolutePath } from '../../shared/internal/mod.ts';\nimport { getParentDirHandle, isRootDir } from '../internal/mod.ts';\n\n/**\n * Retrieves the `FileSystemHandle` for a file or directory at the specified path.\n * Can be used to check the type (file or directory) and access metadata.\n *\n * @param path - The absolute path of the file or directory.\n * @returns A promise that resolves to an `AsyncIOResult` containing the `FileSystemHandle`.\n * @since 1.0.0\n * @see {@link statSync} for synchronous version\n * @see {@link exists} for checking existence without getting the handle\n * @see {@link isFileHandle} for checking handle type\n * @see {@link isDirectoryHandle} for checking handle type\n * @example\n * ```typescript\n * (await stat('/path/to/entry'))\n *     .inspect(handle => console.log(`Kind: ${ handle.kind }, Name: ${ handle.name }`));\n * ```\n */\nexport async function stat(path: string): AsyncIOResult<FileSystemHandle> {\n    const pathRes = validateAbsolutePath(path);\n    if (pathRes.isErr()) return pathRes.asErr();\n    path = pathRes.unwrap();\n\n    const dirHandleRes = await getParentDirHandle(path);\n    if (isRootDir(path)) {\n        // root\n        return dirHandleRes;\n    }\n\n    return dirHandleRes.andThenAsync(async dirHandle => {\n        // Try to get the handle directly instead of iterating\n        // First try as file, then as directory\n        const childName = basename(path);\n        let findRes = await tryAsyncResult<FileSystemHandle, DOMException>(dirHandle.getFileHandle(childName));\n        if (findRes.isOk()) {\n            return findRes;\n        }\n\n        // Not a file, try as directory\n        findRes = await tryAsyncResult<FileSystemHandle, DOMException>(dirHandle.getDirectoryHandle(childName));\n\n        return findRes.mapErr(err => {\n            const error = new Error(`${ err.name }: '${ childName }' does not exist. Full path is '${ path }'`);\n            error.name = err.name;\n            return error;\n        });\n    });\n}\n","import { Err, type AsyncVoidIOResult } from 'happy-rusty';\nimport { validateAbsolutePath } from '../../shared/internal/mod.ts';\nimport { getFileHandle } from '../internal/mod.ts';\n\n/**\n * Truncates (resizes) a file to the specified size.\n *\n * If `len` is smaller than the current file size, the file is shortened and\n * the trailing data is discarded. If `len` is larger, the file is extended\n * with zero bytes (`\\x00`).\n *\n * The file must already exist; this operation never creates a new file.\n * Truncating a directory path returns a `TypeMismatchError`.\n *\n * @param filePath - The absolute path of the file to truncate.\n * @param len - The target size in bytes. Must be a non-negative integer.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 2.2.0\n * @see {@link truncateSync} for synchronous version\n * @example\n * ```typescript\n * await writeFile('/log.txt', 'Hello, World!');\n * await truncate('/log.txt', 5);   // file now contains \"Hello\"\n * await truncate('/log.txt', 8);   // file now contains \"Hello\\x00\\x00\\x00\"\n * ```\n */\nexport async function truncate(filePath: string, len: number): AsyncVoidIOResult {\n    const filePathRes = validateAbsolutePath(filePath);\n    if (filePathRes.isErr()) return filePathRes.asErr();\n    filePath = filePathRes.unwrap();\n\n    if (!Number.isInteger(len) || len < 0) {\n        return Err(new TypeError(`Size must be a non-negative integer, got ${ len }`));\n    }\n\n    const fileHandleRes = await getFileHandle(filePath, { create: false });\n    return fileHandleRes.andTryAsync(async fileHandle => {\n        // Prefer sync access handle in Worker for better performance\n        if (typeof fileHandle.createSyncAccessHandle === 'function') {\n            const accessHandle = await fileHandle.createSyncAccessHandle();\n            try {\n                accessHandle.truncate(len);\n            } finally {\n                accessHandle.close();\n            }\n            return;\n        }\n\n        // Main thread fallback: keep existing data, then resize\n        const writable = await fileHandle.createWritable({ keepExistingData: true });\n        try {\n            await writable.truncate(len);\n        } finally {\n            await writable.close();\n        }\n    });\n}\n","import { tryAsyncResult, type AsyncIOResult, type AsyncVoidIOResult } from 'happy-rusty';\nimport { readBlobBytesSync, toBytesView, validateAbsolutePath, validateWriteFileContent } from '../../shared/internal/mod.ts';\nimport type { WriteFileContent, WriteOptions } from '../../shared/mod.ts';\nimport { generateTempPath } from '../../shared/mod.ts';\nimport { getFileHandle, isNotFoundError, moveFileHandle } from '../internal/mod.ts';\nimport { remove } from './remove.ts';\n\n/**\n * Writes content to a file at the specified path.\n * Creates the file and parent directories if they don't exist (unless `create: false`).\n *\n * When writing a `ReadableStream` to a **new file**, the stream is first written to a temporary\n * file in `/tmp`, then moved to the target path upon success. This prevents leaving incomplete\n * files if the stream is interrupted. For existing files, writes are performed directly since\n * OPFS's transactional writes preserve the original content on failure.\n *\n * @param filePath - The absolute path of the file to write to.\n * @param contents - The content to write (string, ArrayBuffer, TypedArray, Blob, or ReadableStream<Uint8Array>).\n * @param options - Optional write options.\n * @param options.create - Whether to create the file if it doesn't exist. Default: `true`.\n * @param options.append - Whether to append to the file instead of overwriting. Default: `false`.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 1.0.0\n * @see {@link writeFileSync} for synchronous version\n * @see {@link appendFile} for appending to files\n * @see {@link writeJsonFile} for writing JSON data\n * @example\n * ```typescript\n * // Write string content\n * await writeFile('/path/to/file.txt', 'Hello, World!');\n *\n * // Write binary content\n * await writeFile('/path/to/file.bin', new Uint8Array([1, 2, 3]));\n *\n * // Append to existing file\n * await writeFile('/path/to/file.txt', '\\nMore content', { append: true });\n * ```\n */\nexport async function writeFile(filePath: string, contents: WriteFileContent, options?: WriteOptions): AsyncVoidIOResult {\n    const filePathRes = validateAbsolutePath(filePath);\n    if (filePathRes.isErr()) return filePathRes.asErr();\n    filePath = filePathRes.unwrap();\n\n    // Validate content type at entry point to prevent silent failures\n    const contentRes = validateWriteFileContent(contents);\n    if (contentRes.isErr()) return contentRes.asErr();\n\n    // For stream content, use temp file strategy when creating new files\n    if (isBinaryReadableStream(contents)) {\n        return writeStreamToFile(filePath, contents, options);\n    }\n\n    const fileHandleRes = await getWriteFileHandle(filePath, options);\n\n    return fileHandleRes.andTryAsync(fileHandle => {\n        const { append = false } = options ?? {};\n\n        // Prefer sync access in Worker for better performance\n        if (typeof fileHandle.createSyncAccessHandle === 'function') {\n            return writeDataViaSyncAccess(fileHandle, contents, append);\n        }\n\n        // Main thread fallback\n        return writeDataViaWritable(fileHandle, contents, append);\n    });\n}\n\n/**\n * Opens a file and returns a writable stream for writing contents.\n * Useful for writing large files without loading them entirely into memory.\n * The caller is responsible for closing the stream when done.\n *\n * @param filePath - The absolute path of the file to write.\n * @param options - Optional write options.\n * @returns A promise that resolves to an `AsyncIOResult` containing a `FileSystemWritableFileStream`.\n * @since 1.0.0\n * @see {@link writeFile} for general file writing\n * @example\n * ```typescript\n * (await openWritableFileStream('/path/to/large-file.bin'))\n *     .inspect(async stream => {\n *         try {\n *             await stream.write(new Uint8Array([1, 2, 3]));\n *             await stream.write(new Uint8Array([4, 5, 6]));\n *         } finally {\n *             await stream.close();\n *         }\n *     });\n * ```\n */\nexport async function openWritableFileStream(filePath: string, options?: WriteOptions): AsyncIOResult<FileSystemWritableFileStream> {\n    const filePathRes = validateAbsolutePath(filePath);\n    if (filePathRes.isErr()) return filePathRes.asErr();\n    filePath = filePathRes.unwrap();\n\n    const fileHandleRes = await getWriteFileHandle(filePath, options);\n\n    return fileHandleRes.andTryAsync(async fileHandle => {\n        const { append = false } = options ?? {};\n\n        const writable = await fileHandle.createWritable({\n            keepExistingData: append,\n        });\n\n        // If appending, seek to end\n        if (append) {\n            try {\n                const { size } = await fileHandle.getFile();\n                await writable.seek(size);\n            } catch (err) {\n                await writable.close();\n                throw err;\n            }\n        }\n\n        return writable;\n    });\n}\n\n/**\n * Gets a file handle for writing, with optional creation.\n */\nfunction getWriteFileHandle(filePath: string, options?: WriteOptions): AsyncIOResult<FileSystemFileHandle> {\n    const { create = true } = options ?? {};\n    return getFileHandle(filePath, { create });\n}\n\n/**\n * Type guard for detecting binary ReadableStream input for file writing.\n */\nfunction isBinaryReadableStream(x: unknown): x is ReadableStream<Uint8Array<ArrayBuffer>> {\n    return typeof ReadableStream !== 'undefined' && x instanceof ReadableStream;\n}\n\n/**\n * Writes a ReadableStream to a file with atomic semantics for new files.\n *\n * Strategy:\n * - If target file exists: write directly (OPFS transactional writes preserve original on failure)\n * - If target file doesn't exist: write to temp file first, then move to target on success\n *\n * This prevents leaving incomplete/empty files when stream is interrupted during new file creation.\n *\n * Assumes filePath is already validated.\n */\nasync function writeStreamToFile(\n    filePath: string,\n    stream: ReadableStream<Uint8Array<ArrayBuffer>>,\n    options?: WriteOptions,\n): AsyncVoidIOResult {\n    const { create = true, append = false } = options ?? {};\n\n    // Check if target file already exists\n    const existHandleRes = await getFileHandle(filePath, { create: false });\n\n    if (existHandleRes.isOk()) {\n        // File exists: write directly (transactional protection)\n        return writeStreamToHandle(existHandleRes.unwrap(), stream, append);\n    }\n\n    // File doesn't exist or unexpected error - return error if not creating or not a NotFoundError\n    if (!create || !isNotFoundError(existHandleRes.unwrapErr())) {\n        return existHandleRes.asErr();\n    }\n\n    // New file: use temp file strategy\n    const tempPath = generateTempPath();\n    const tempHandleRes = await getFileHandle(tempPath, { create: true });\n    if (tempHandleRes.isErr()) {\n        return tempHandleRes.asErr();\n    }\n\n    const tempHandle = tempHandleRes.unwrap();\n    const writeRes = await writeStreamToHandle(tempHandle, stream, false);\n\n    if (writeRes.isErr()) {\n        // Clean up temp file on failure\n        await remove(tempPath);\n        return writeRes;\n    }\n\n    // Move temp file to target path (this creates parent directories if needed)\n    const moveRes = await moveFileHandle(tempHandle, filePath);\n    if (moveRes.isErr()) {\n        // Clean up temp file\n        await remove(tempPath);\n    }\n\n    return moveRes;\n}\n\n/**\n * Writes a stream to a file handle using the appropriate API.\n */\nasync function writeStreamToHandle(\n    fileHandle: FileSystemFileHandle,\n    stream: ReadableStream<Uint8Array<ArrayBuffer>>,\n    append: boolean,\n): AsyncVoidIOResult {\n    return tryAsyncResult(() => {\n        // Prefer sync access in Worker for better performance\n        if (typeof fileHandle.createSyncAccessHandle === 'function') {\n            return writeStreamViaSyncAccess(fileHandle, stream, append);\n        }\n        // Main thread fallback\n        return writeStreamViaWritable(fileHandle, stream, append);\n    });\n}\n\n/**\n * Writes a ReadableStream to a file using the main thread's FileSystemWritableFileStream API.\n */\nasync function writeStreamViaWritable(\n    fileHandle: FileSystemFileHandle,\n    stream: ReadableStream<Uint8Array<ArrayBuffer>>,\n    append: boolean,\n): Promise<void> {\n    const writable = await fileHandle.createWritable({\n        keepExistingData: append,\n    });\n\n    if (append) {\n        const { size } = await fileHandle.getFile();\n        await writable.seek(size);\n    }\n\n    return stream.pipeTo(writable);\n}\n\n/**\n * Writes non-stream data to a file using the main thread's FileSystemWritableFileStream API.\n */\nasync function writeDataViaWritable(\n    fileHandle: FileSystemFileHandle,\n    contents: Exclude<WriteFileContent, ReadableStream>,\n    append: boolean,\n): Promise<void> {\n    const writable = await fileHandle.createWritable({\n        keepExistingData: append,\n    });\n\n    try {\n        const params: WriteParams = {\n            type: 'write',\n            data: contents,\n        };\n\n        if (append) {\n            const { size } = await fileHandle.getFile();\n            params.position = size;\n        }\n\n        return writable.write(params);\n    } finally {\n        await writable.close();\n    }\n}\n\n/**\n * Writes a ReadableStream to a file using the Worker's FileSystemSyncAccessHandle API.\n */\nasync function writeStreamViaSyncAccess(\n    fileHandle: FileSystemFileHandle,\n    stream: ReadableStream<Uint8Array<ArrayBuffer>>,\n    append: boolean,\n): Promise<void> {\n    const accessHandle = await fileHandle.createSyncAccessHandle();\n\n    try {\n        if (!append) {\n            accessHandle.truncate(0);\n        }\n\n        let position = append ? accessHandle.getSize() : 0;\n\n        for await (const chunk of stream) {\n            position = writeBytesWithRetry(accessHandle, chunk, position);\n        }\n    } finally {\n        accessHandle.close();\n    }\n}\n\n/**\n * Writes non-stream data to a file using the Worker's FileSystemSyncAccessHandle API.\n */\nasync function writeDataViaSyncAccess(\n    fileHandle: FileSystemFileHandle,\n    contents: Exclude<WriteFileContent, ReadableStream>,\n    append: boolean,\n): Promise<void> {\n    const accessHandle = await fileHandle.createSyncAccessHandle();\n\n    try {\n        // Always write as Uint8Array to avoid copying buffer.\n        // Blob must be handled separately (readBlobBytesSync) before toBytesView,\n        // since toBytesView does not accept Blob.\n        const bytes = contents instanceof Blob\n            ? readBlobBytesSync(contents)\n            : toBytesView(contents);\n\n        if (!append) {\n            accessHandle.truncate(0);\n        }\n\n        const position = append ? accessHandle.getSize() : 0;\n        writeBytesWithRetry(accessHandle, bytes, position);\n    } finally {\n        accessHandle.close();\n    }\n}\n\n/**\n * Writes bytes to a FileSystemSyncAccessHandle with retry logic for partial writes.\n * Returns the final position after writing.\n */\nfunction writeBytesWithRetry(\n    accessHandle: FileSystemSyncAccessHandle,\n    bytes: Uint8Array<ArrayBuffer>,\n    position: number,\n): number {\n    let remaining = bytes;\n    let currentPosition = position;\n\n    while (remaining.byteLength > 0) {\n        const written = accessHandle.write(remaining, {\n            at: currentPosition,\n        });\n\n        currentPosition += written;\n\n        if (written >= remaining.byteLength) {\n            break;\n        }\n\n        // Create a new Uint8Array for the remaining part without copying buffer.\n        remaining = remaining.subarray(written);\n    }\n\n    return currentPosition;\n}\n","import { join, SEPARATOR } from '@std/path/posix';\nimport { Err, RESULT_FALSE, RESULT_VOID, tryAsyncResult, tryResult, type AsyncIOResult, type AsyncVoidIOResult } from 'happy-rusty';\nimport { validateAbsolutePath, validateExistsOptions } from '../shared/internal/mod.ts';\nimport { isDirectoryHandle, isFileHandle, type AppendOptions, type CopyOptions, type ExistsOptions, type MoveOptions, type WriteFileContent } from '../shared/mod.ts';\nimport { mkdir, readDir, readFile, remove, stat, writeFile } from './core/mod.ts';\nimport { aggregateResults, isNotFoundError, isRootDir, markParentDirsNonEmpty, moveFileHandle } from './internal/mod.ts';\n\n/**\n * Appends content to a file at the specified path.\n * Creates the file if it doesn't exist (unless `create: false` is specified).\n *\n * @param filePath - The absolute path of the file to append to.\n * @param contents - The content to append (string, ArrayBuffer, TypedArray, or Blob).\n * @param options - Optional append options.\n * @param options.create - Whether to create the file if it doesn't exist. Default: `true`.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 1.0.0\n * @see {@link writeFile} with `append: true` option\n * @example\n * ```typescript\n * // Append to file, create if doesn't exist (default behavior)\n * await appendFile('/path/to/log.txt', 'New log entry\\n');\n *\n * // Append only if file exists, fail if it doesn't\n * await appendFile('/path/to/log.txt', 'New log entry\\n', { create: false });\n * ```\n */\nexport function appendFile(filePath: string, contents: WriteFileContent, options?: AppendOptions): AsyncVoidIOResult {\n    return writeFile(filePath, contents, {\n        append: true,\n        create: options?.create,\n    });\n}\n\n/**\n * Copies a file or directory from one location to another, similar to `cp -r`.\n * Both source and destination must be of the same type (both files or both directories).\n *\n * @param srcPath - The absolute source path.\n * @param destPath - The absolute destination path.\n * @param options - Optional copy options.\n * @param options.overwrite - Whether to overwrite existing files. Default: `true`.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 1.7.0\n * @see {@link move} for moving instead of copying\n * @example\n * ```typescript\n * // Copy a file\n * await copy('/src/file.txt', '/dest/file.txt');\n *\n * // Copy a directory\n * await copy('/src/folder', '/dest/folder');\n *\n * // Copy without overwriting existing files\n * await copy('/src', '/dest', { overwrite: false });\n * ```\n */\nexport function copy(srcPath: string, destPath: string, options?: CopyOptions): AsyncVoidIOResult {\n    return mkDestFromSrc(srcPath, destPath, copyFileHandle, 'copy', options?.overwrite);\n}\n\n/**\n * Empties all contents of a directory at the specified path.\n * If the directory doesn't exist, it will be created.\n *\n * @param dirPath - The absolute path of the directory to empty.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 1.0.9\n * @see {@link mkdir} for creating directories\n * @see {@link remove} for removing directories\n * @example\n * ```typescript\n * await emptyDir('/path/to/directory');\n * ```\n */\nexport async function emptyDir(dirPath: string): AsyncVoidIOResult {\n    // For root directory, remove() clears all contents\n    if (isRootDir(dirPath)) {\n        return remove(dirPath);\n    }\n\n    // Check if path is a directory\n    const statRes = await stat(dirPath);\n    if (statRes.isErr()) {\n        // Create if not exist\n        return isNotFoundError(statRes.unwrapErr())\n            ? mkdir(dirPath)\n            : statRes.asErr();\n    }\n\n    if (isFileHandle(statRes.unwrap())) {\n        return Err(new Error(`Path '${ dirPath }' is not a directory`));\n    }\n\n    // Remove and recreate directory (OPFS has no metadata to preserve)\n    const removeRes = await remove(dirPath);\n    return removeRes.andThenAsync(() => mkdir(dirPath));\n}\n\n/**\n * Checks whether a file or directory exists at the specified path.\n *\n * @param path - The absolute path to check.\n * @param options - Optional existence options. Set `isDirectory: true` to check for directory,\n *                  or `isFile: true` to check for file. Cannot set both to `true`.\n * @returns A promise that resolves to an `AsyncIOResult<boolean>` indicating existence.\n * @since 1.0.0\n * @see {@link existsSync} for synchronous version\n * @see {@link stat} for getting the handle\n * @example\n * ```typescript\n * // Check if path exists (file or directory)\n * const exists = await exists('/path/to/entry');\n *\n * // Check if path exists and is a file\n * const isFile = await exists('/path/to/file', { isFile: true });\n *\n * // Check if path exists and is a directory\n * const isDir = await exists('/path/to/dir', { isDirectory: true });\n * ```\n */\nexport async function exists(path: string, options?: ExistsOptions): AsyncIOResult<boolean> {\n    const optionsRes = validateExistsOptions(options);\n    if (optionsRes.isErr()) return optionsRes.asErr();\n\n    const statRes = await stat(path);\n\n    return statRes.map(handle => {\n        const { isDirectory = false, isFile = false } = options ?? {};\n        const notExist =\n            (isDirectory && isFileHandle(handle))\n            || (isFile && isDirectoryHandle(handle));\n        return !notExist;\n    }).orElse(err => {\n        return isNotFoundError(err) ? RESULT_FALSE : statRes.asErr();\n    });\n}\n\n/**\n * Moves a file or directory from one location to another.\n * Both source and destination must be of the same type (both files or both directories).\n *\n * @param srcPath - The absolute source path.\n * @param destPath - The absolute destination path.\n * @param options - Optional move options.\n * @param options.overwrite - Whether to overwrite existing files. Default: `true`.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 1.8.0\n * @see {@link copy} for copying instead of moving\n * @example\n * ```typescript\n * // Move/rename a file\n * await move('/old/path/file.txt', '/new/path/file.txt');\n *\n * // Move a directory\n * await move('/old/folder', '/new/folder');\n * ```\n */\nexport async function move(srcPath: string, destPath: string, options?: MoveOptions): AsyncVoidIOResult {\n    const mkRes = await mkDestFromSrc(srcPath, destPath, moveFileHandle, 'move', options?.overwrite);\n    return mkRes.andThenAsync(() => remove(srcPath));\n}\n\n/**\n * Reads the content of a file as a `File` object (Blob with name).\n *\n * @param filePath - The absolute path of the file to read.\n * @returns A promise that resolves to an `AsyncIOResult` containing the `File` object.\n * @since 1.0.0\n * @see {@link readFile} with `encoding: 'blob'`\n * @see {@link uploadFile} for uploading files\n * @example\n * ```typescript\n * (await readBlobFile('/path/to/file.txt'))\n *     .inspect(file => console.log(file.name, file.size, file.type));\n * ```\n */\nexport function readBlobFile(filePath: string): AsyncIOResult<File> {\n    return readFile(filePath, {\n        encoding: 'blob',\n    });\n}\n\n/**\n * Reads a JSON file and parses its content.\n *\n * @template T - The expected type of the parsed JSON object.\n * @param filePath - The path of the JSON file to read.\n * @returns A promise that resolves to an `AsyncIOResult` containing the parsed JSON object.\n * @since 1.8.4\n * @see {@link writeJsonFile} for the reverse operation\n * @see {@link readTextFile} for reading raw text\n * @example\n * ```typescript\n * interface Config {\n *     name: string;\n *     version: number;\n * }\n * (await readJsonFile<Config>('/config.json'))\n *     .inspect(config => console.log(config.name));\n * ```\n */\nexport async function readJsonFile<T>(filePath: string): AsyncIOResult<T> {\n    const readRes = await readTextFile(filePath);\n    return readRes.andThen(text => tryResult<T, Error, [string]>(JSON.parse, text));\n}\n\n/**\n * Reads a file as a UTF-8 string.\n *\n * @param filePath - The absolute path of the file to read.\n * @returns A promise that resolves to an `AsyncIOResult` containing the file content as a string.\n * @since 1.0.0\n * @see {@link readFile} with `encoding: 'utf8'`\n * @see {@link readJsonFile} for reading JSON files\n * @example\n * ```typescript\n * (await readTextFile('/path/to/file.txt'))\n *     .inspect(content => console.log(content));\n * ```\n */\nexport function readTextFile(filePath: string): AsyncIOResult<string> {\n    return readFile(filePath, {\n        encoding: 'utf8',\n    });\n}\n\n/**\n * Writes an object to a file as JSON.\n *\n * @template T - The type of the object to write.\n * @param filePath - The absolute path of the file to write.\n * @param data - The object to serialize and write.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 1.0.0\n * @see {@link readJsonFile} for the reverse operation\n * @see {@link writeFile} for writing raw content\n * @example\n * ```typescript\n * const config = { name: 'app', version: 1 };\n * (await writeJsonFile('/config.json', config))\n *     .inspect(() => console.log('Config saved'));\n * ```\n */\nexport function writeJsonFile<T>(filePath: string, data: T): AsyncVoidIOResult {\n    const result = tryResult(JSON.stringify, data);\n    return result.andThenAsync(text => writeFile(filePath, text));\n}\n\n// #region Internal Types\n\n/**\n * Handler function type for processing source file to destination.\n *\n * @param srcFileHandle - The source file handle to process.\n * @param destFilePath - The destination file path.\n */\ntype HandleSrcFileToDest = (srcFileHandle: FileSystemFileHandle, destFilePath: string) => AsyncVoidIOResult;\n\n// #endregion\n\n// #region Internal Functions\n\n/**\n * Copies a file handle to a new path by reading and writing the file content.\n *\n * @param fileHandle - The file handle to copy.\n * @param destFilePath - The destination absolute path for the file.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n */\nasync function copyFileHandle(fileHandle: FileSystemFileHandle, destFilePath: string): AsyncVoidIOResult {\n    const fileRes = await tryAsyncResult(fileHandle.getFile());\n    return fileRes.andThenAsync(file => writeFile(destFilePath, file));\n}\n\n/**\n * Internal helper that copies or moves a file/directory from source to destination.\n *\n * Algorithm:\n * 1. Verify source exists via stat()\n * 2. Check if destination exists and validate type compatibility (file-to-file or dir-to-dir)\n * 3. For files: directly apply handler (copy or move)\n * 4. For directories: recursively process all entries in parallel\n * 5. Respect overwrite flag - skip if dest exists and overwrite=false\n *\n * @param srcPath - The source file/directory path.\n * @param destPath - The destination file/directory path.\n * @param handler - The function to handle file transfer (copy or move).\n * @param opName - The operation name for error messages ('copy' or 'move').\n * @param overwrite - Whether to overwrite existing files. Default: `true`.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n */\nasync function mkDestFromSrc(\n    srcPath: string,\n    destPath: string,\n    handler: HandleSrcFileToDest,\n    opName: 'copy' | 'move',\n    overwrite = true,\n): AsyncVoidIOResult {\n    const srcPathRes = validateAbsolutePath(srcPath);\n    if (srcPathRes.isErr()) return srcPathRes.asErr();\n    srcPath = srcPathRes.unwrap();\n\n    const destPathRes = validateAbsolutePath(destPath);\n    if (destPathRes.isErr()) return destPathRes.asErr();\n    destPath = destPathRes.unwrap();\n\n    // Prevent copying/moving a directory into itself\n    // For root directory, any destPath is a subdirectory\n    if (isRootDir(srcPath) || destPath.startsWith(srcPath + SEPARATOR) || destPath === srcPath) {\n        return Err(new Error(`Cannot ${ opName } '${ srcPath }' into itself '${ destPath }'`));\n    }\n\n    const statRes = await stat(srcPath);\n    if (statRes.isErr()) {\n        return statRes.asErr();\n    }\n\n    const srcHandle = statRes.unwrap();\n    // Track whether destination already exists (needed for overwrite logic)\n    let destExists = false;\n\n    const destHandleRes = await stat(destPath);\n    if (destHandleRes.isErr()) {\n        // Destination doesn't exist - that's OK unless it's an unexpected error\n        if (!isNotFoundError(destHandleRes.unwrapErr())) {\n            return destHandleRes.asErr();\n        }\n    } else {\n        destExists = true;\n        // Validate type compatibility: both must be files OR both must be directories\n        const destHandle = destHandleRes.unwrap();\n        if (\n            !(isFileHandle(srcHandle) && isFileHandle(destHandle))\n            && !(isDirectoryHandle(srcHandle) && isDirectoryHandle(destHandle))\n        ) {\n            return Err(new Error(`Source '${ srcPath }' and destination '${ destPath }' must both be files or both be directories`));\n        }\n    }\n\n    // Handle file source: apply handler directly\n    if (isFileHandle(srcHandle)) {\n        return (overwrite || !destExists) ? await handler(srcHandle, destPath) : RESULT_VOID;\n    }\n\n    // Handle directory source: recursively process all entries\n    const readDirRes = await readDir(srcPath, {\n        recursive: true,\n    });\n    if (readDirRes.isErr()) {\n        return readDirRes.asErr();\n    }\n\n    // Collect all tasks for parallel execution\n    const tasks: AsyncVoidIOResult[] = [];\n    const dirs: string[] = [];\n    const nonEmptyDirs = new Set<string>();\n\n    try {\n        for await (const { path, handle } of readDirRes.unwrap()) {\n            if (isFileHandle(handle)) {\n                const newFilePath = join(destPath, path);\n\n                // Wrap file processing in an async IIFE for parallel execution\n                tasks.push((async () => {\n                    let newPathExists = false;\n\n                    if (destExists) {\n                    // Destination dir exists, need to check each file individually\n                        const existsRes = await exists(newFilePath);\n                        if (existsRes.isErr()) {\n                            return existsRes.asErr();\n                        }\n\n                        newPathExists = existsRes.unwrap();\n                    }\n\n                    return overwrite || !newPathExists ? handler(handle, newFilePath) : RESULT_VOID;\n                })());\n\n                // Mark all parent directories as non-empty\n                markParentDirsNonEmpty(path, nonEmptyDirs);\n            } else {\n                dirs.push(path);\n            }\n        }\n    } catch (e) {\n        return Err(e as Error);\n    }\n\n    // Only create truly empty directories\n    for (const dir of dirs) {\n        if (!nonEmptyDirs.has(dir)) {\n            tasks.push(mkdir(join(destPath, dir)));\n        }\n    }\n\n    // Handle empty source directory case\n    if (tasks.length === 0 && !destExists) {\n        return mkdir(destPath);\n    }\n\n    // Wait for all tasks and return first error if any\n    return aggregateResults(tasks);\n}\n\n// #endregion\n","/**\n * Internal helper utilities for archive operations.\n *\n * @internal\n * @module\n */\n\nimport { Err, type AsyncIOResult } from 'happy-rusty';\nimport { validateAbsolutePath } from '../../shared/internal/mod.ts';\nimport { exists } from '../ext.ts';\n\n/**\n * Empty bytes constant, used for directory entries in zip or empty file content.\n */\nexport const EMPTY_BYTES: Uint8Array<ArrayBuffer> = /*#__PURE__*/ new Uint8Array(0);\n\n/**\n * Validates that destDir is an absolute path and is not an existing file.\n * If destDir doesn't exist, that's fine (it will be created).\n * If destDir exists and is a directory, that's fine.\n * If destDir exists and is a file, return an error.\n *\n * @param destDir - The destination directory path to validate.\n * @returns An `AsyncIOResult` containing the normalized path, or an error.\n */\nexport async function validateDestDir(destDir: string): AsyncIOResult<string> {\n    const pathRes = validateAbsolutePath(destDir);\n    if (pathRes.isErr()) return pathRes;\n    destDir = pathRes.unwrap();\n\n    const existsRes = await exists(destDir, { isFile: true });\n\n    return existsRes.andThen(isFile => {\n        return isFile\n            ? Err(new Error(`Path '${ destDir }' is not a directory`))\n            : pathRes;\n    });\n}\n","import { fetchT } from '@happy-ts/fetch-t';\nimport { join, SEPARATOR } from '@std/path/posix';\nimport { AsyncUnzipInflate, Unzip, UnzipPassThrough, type UnzipFile } from 'fflate/browser';\nimport { Err, type AsyncIOResult, type AsyncVoidIOResult } from 'happy-rusty';\nimport { validateUrl } from '../../shared/internal/mod.ts';\nimport type { UnzipFromUrlRequestInit } from '../../shared/mod.ts';\nimport { mkdir, readFile, writeFile } from '../core/mod.ts';\nimport { aggregateResults, createEmptyBodyError, createEmptyFileError, markParentDirsNonEmpty } from '../internal/mod.ts';\nimport { EMPTY_BYTES, validateDestDir } from './helpers.ts';\n\n/**\n * Unzip a zip file to a directory using streaming decompression.\n * Equivalent to `unzip -o <zipFilePath> -d <destDir>`\n *\n * This function processes the zip file incrementally, minimizing memory usage.\n * Recommended for large files (>10MB). For small files, consider using {@link unzip} instead.\n *\n * Use [fflate](https://github.com/101arrowz/fflate) as the unzip backend.\n *\n * @param zipFilePath - Zip file path.\n * @param destDir - The directory to unzip to.\n * @returns A promise that resolves to an `AsyncIOResult` indicating whether the zip file was successfully unzipped.\n * @since 2.0.0\n * @see {@link unzip} for batch version (faster for small files)\n * @see {@link zipStream} for the reverse operation\n * @example\n * ```typescript\n * (await unzipStream('/downloads/large-archive.zip', '/extracted'))\n *     .inspect(() => console.log('Unzipped successfully'));\n * ```\n */\nexport async function unzipStream(zipFilePath: string, destDir: string): AsyncVoidIOResult {\n    return unzipStreamWith(\n        () => readFile(zipFilePath, { encoding: 'stream' }),\n        destDir,\n        createEmptyFileError,\n    );\n}\n\n/**\n * Unzip a remote zip file to a directory using streaming decompression.\n * Equivalent to `unzip -o <zipFilePath> -d <destDir>`\n *\n * This function processes the zip file incrementally, minimizing memory usage.\n * Recommended for large files (>10MB). For small files, consider using {@link unzipFromUrl} instead.\n *\n * Use [fflate](https://github.com/101arrowz/fflate) as the unzip backend.\n *\n * This API is built on `@happy-ts/fetch-t` for downloading the zip file.\n * `options` supports `timeout` and `onProgress` options.\n *\n * @param zipFileUrl - Zip file url.\n * @param destDir - The directory to unzip to.\n * @param requestInit - Optional request options.\n * @returns A promise that resolves to an `AsyncIOResult` indicating whether the zip file was successfully unzipped.\n * @since 2.0.0\n * @see {@link unzipFromUrl} for batch version (faster for small files)\n * @see {@link zipStreamFromUrl} for the reverse operation\n * @example\n * ```typescript\n * (await unzipStreamFromUrl('https://example.com/large-archive.zip', '/extracted'))\n *     .inspect(() => console.log('Remote zip file unzipped successfully'));\n *\n * // With timeout\n * (await unzipStreamFromUrl('https://example.com/archive.zip', '/extracted', { timeout: 30000 }))\n *     .inspect(() => console.log('Remote zip file unzipped successfully'));\n * ```\n */\nexport async function unzipStreamFromUrl(zipFileUrl: string | URL, destDir: string, requestInit?: UnzipFromUrlRequestInit): AsyncVoidIOResult {\n    const zipFileUrlRes = validateUrl(zipFileUrl);\n    if (zipFileUrlRes.isErr()) return zipFileUrlRes.asErr();\n    zipFileUrl = zipFileUrlRes.unwrap();\n\n    return unzipStreamWith(\n        () => fetchT(zipFileUrl, {\n            redirect: 'follow',\n            ...requestInit,\n            responseType: 'stream',\n            abortable: false,\n        }),\n        destDir,\n        createEmptyBodyError,\n    );\n}\n\n// #region Internal Functions\n\n/**\n * Common streaming unzip implementation for both local and remote sources.\n * @param getStream - Function to get the readable stream.\n * @param destDir - Destination directory path.\n * @param createEmptyError - Function to create error for empty data.\n */\nasync function unzipStreamWith(\n    getStream: () => AsyncIOResult<ReadableStream<Uint8Array<ArrayBuffer>> | null>,\n    destDir: string,\n    createEmptyError: () => Error,\n): AsyncVoidIOResult {\n    const destDirRes = await validateDestDir(destDir);\n    if (destDirRes.isErr()) return destDirRes.asErr();\n    destDir = destDirRes.unwrap();\n\n    const streamRes = await getStream();\n    if (streamRes.isErr()) return streamRes.asErr();\n    const stream = streamRes.unwrap();\n\n    // stream can be null for 204/304 responses\n    if (!stream) {\n        return Err(createEmptyError());\n    }\n\n    return streamUnzipTo(stream, destDir, createEmptyError);\n}\n\n/**\n * Stream unzip from a ReadableStream to destination directory.\n * Uses fflate's streaming Unzip API to minimize memory usage.\n *\n * @param stream - The readable stream containing zip data.\n * @param destDir - Destination directory path.\n * @param createEmptyError - Function to create error for empty data.\n */\nasync function streamUnzipTo(\n    stream: ReadableStream<Uint8Array<ArrayBuffer>>,\n    destDir: string,\n    createEmptyError: () => Error,\n): AsyncVoidIOResult {\n    // Track directories and files for proper handling\n    const tasks: AsyncVoidIOResult[] = [];\n    const dirs: string[] = [];\n    const nonEmptyDirs = new Set<string>();\n    let hasData = false;\n\n    const unzipper = new Unzip();\n    // Register decompression handlers\n    unzipper.register(UnzipPassThrough); // For stored (uncompressed) files\n    unzipper.register(AsyncUnzipInflate); // For deflated files\n\n    unzipper.onfile = file => {\n        const path = file.name;\n\n        if (path.at(-1) === SEPARATOR) {\n            // Directory entry - collect for later creation\n            dirs.push(path.slice(0, -1));\n        } else {\n            // Create a promise for this file's extraction\n            tasks.push(extractFile(file, join(destDir, path)));\n            // File entry - mark parent directories as non-empty\n            markParentDirsNonEmpty(path, nonEmptyDirs);\n        }\n    };\n\n    try {\n        for await (const chunk of stream) {\n            hasData = true;\n            unzipper.push(chunk, false);\n        }\n        // Signal end of stream\n        unzipper.push(EMPTY_BYTES, true);\n    } catch (err) {\n        return Err(err as Error);\n    }\n\n    // Empty stream check\n    if (!hasData) {\n        return Err(createEmptyError());\n    }\n\n    // Add empty directory creation tasks\n    for (const dir of dirs) {\n        if (!nonEmptyDirs.has(dir)) {\n            tasks.push(mkdir(join(destDir, dir)));\n        }\n    }\n\n    return aggregateResults(tasks);\n}\n\n/**\n * Extract a single file from the unzip stream using streaming write.\n *\n * @param file - The UnzipFile object from fflate.\n * @param destPath - The destination path for this file.\n */\nfunction extractFile(file: UnzipFile, destPath: string): AsyncVoidIOResult {\n    // Convert UnzipFile to ReadableStream\n    const stream = new ReadableStream<Uint8Array<ArrayBuffer>>({\n        start(controller) {\n            file.ondata = (err, data, final) => {\n                if (err) {\n                    controller.error(err);\n                    return;\n                }\n\n                controller.enqueue(data as Uint8Array<ArrayBuffer>);\n\n                if (final) {\n                    controller.close();\n                }\n            };\n\n            file.start();\n        },\n    });\n\n    return writeFile(destPath, stream);\n}\n\n// #endregion\n","import { fetchT } from '@happy-ts/fetch-t';\nimport { join, SEPARATOR } from '@std/path/posix';\nimport { unzip as decompress } from 'fflate/browser';\nimport { Err, type AsyncIOResult, type AsyncVoidIOResult, type VoidIOResult } from 'happy-rusty';\nimport { Future } from 'tiny-future';\nimport { validateUrl } from '../../shared/internal/mod.ts';\nimport type { UnzipFromUrlRequestInit } from '../../shared/mod.ts';\nimport { mkdir, readFile, writeFile } from '../core/mod.ts';\nimport { aggregateResults, createEmptyBodyError, createEmptyFileError, markParentDirsNonEmpty } from '../internal/mod.ts';\nimport { validateDestDir } from './helpers.ts';\n\n/**\n * Unzip a zip file to a directory using batch decompression.\n * Equivalent to `unzip -o <zipFilePath> -d <destDir>`\n *\n * This function loads the entire zip file into memory before decompression.\n * Faster for small files (<5MB). For large files, consider using {@link unzipStream} instead.\n *\n * Use [fflate](https://github.com/101arrowz/fflate) as the unzip backend.\n *\n * @param zipFilePath - Zip file path.\n * @param destDir - The directory to unzip to.\n * @returns A promise that resolves to an `AsyncIOResult` indicating whether the zip file was successfully unzipped.\n * @since 1.6.0\n * @see {@link unzipSync} for synchronous version\n * @see {@link unzipStream} for streaming version (better for large files)\n * @see {@link zip} for the reverse operation\n * @example\n * ```typescript\n * (await unzip('/downloads/archive.zip', '/extracted'))\n *     .inspect(() => console.log('Unzipped successfully'));\n * ```\n */\nexport async function unzip(zipFilePath: string, destDir: string): AsyncVoidIOResult {\n    return unzipWith(\n        () => readFile(zipFilePath),\n        destDir,\n        createEmptyFileError,\n    );\n}\n\n/**\n * Unzip a remote zip file to a directory using batch decompression.\n * Equivalent to `unzip -o <zipFilePath> -d <destDir>`\n *\n * This function loads the entire zip file into memory before decompression.\n * Faster for small files (<5MB). For large files, consider using {@link unzipStreamFromUrl} instead.\n *\n * Use [fflate](https://github.com/101arrowz/fflate) as the unzip backend.\n *\n * This API is built on `@happy-ts/fetch-t` for downloading the zip file.\n * `options` supports `timeout` and `onProgress` options.\n *\n * @param zipFileUrl - Zip file url.\n * @param destDir - The directory to unzip to.\n * @param requestInit - Optional request options.\n * @returns A promise that resolves to an `AsyncIOResult` indicating whether the zip file was successfully unzipped.\n * @since 1.7.0\n * @see {@link unzipStreamFromUrl} for streaming version (better for large files)\n * @see {@link zipFromUrl} for the reverse operation\n * @example\n * ```typescript\n * (await unzipFromUrl('https://example.com/archive.zip', '/extracted'))\n *     .inspect(() => console.log('Remote zip file unzipped successfully'));\n *\n * // With timeout\n * (await unzipFromUrl('https://example.com/archive.zip', '/extracted', { timeout: 5000 }))\n *     .inspect(() => console.log('Remote zip file unzipped successfully'));\n * ```\n */\nexport async function unzipFromUrl(zipFileUrl: string | URL, destDir: string, requestInit?: UnzipFromUrlRequestInit): AsyncVoidIOResult {\n    const zipFileUrlRes = validateUrl(zipFileUrl);\n    if (zipFileUrlRes.isErr()) return zipFileUrlRes.asErr();\n    zipFileUrl = zipFileUrlRes.unwrap();\n\n    return unzipWith(\n        () => fetchT(zipFileUrl, {\n            redirect: 'follow',\n            ...requestInit,\n            responseType: 'bytes',\n            abortable: false,\n        }),\n        destDir,\n        createEmptyBodyError,\n    );\n}\n\n// #region Internal Functions\n\n/**\n * Common unzip implementation for both local and remote sources.\n * @param getBytes - Function to get zip data.\n * @param destDir - Destination directory path.\n * @param createEmptyError - Function to create error for empty data.\n */\nasync function unzipWith(\n    getBytes: () => AsyncIOResult<Uint8Array<ArrayBuffer>>,\n    destDir: string,\n    createEmptyError: () => Error,\n): AsyncVoidIOResult {\n    const destDirRes = await validateDestDir(destDir);\n    if (destDirRes.isErr()) return destDirRes.asErr();\n    destDir = destDirRes.unwrap();\n\n    const bytesRes = await getBytes();\n\n    return bytesRes.andThenAsync(bytes => {\n        return bytes.byteLength === 0\n            ? Err(createEmptyError())\n            : batchUnzipTo(bytes, destDir);\n    });\n}\n\n/**\n * Unzip a buffer then write to the destination directory.\n * @param bytes - Zipped Uint8Array.\n * @param destDir - Destination directory path.\n */\nfunction batchUnzipTo(bytes: Uint8Array<ArrayBuffer>, destDir: string): AsyncVoidIOResult {\n    const future = new Future<VoidIOResult>();\n\n    decompress(bytes, async (err, unzipped) => {\n        if (err) {\n            future.resolve(Err(err));\n            return;\n        }\n\n        // Collect all tasks for parallel execution\n        const tasks: AsyncVoidIOResult[] = [];\n        const dirs: string[] = [];\n        const nonEmptyDirs = new Set<string>();\n\n        for (const path in unzipped) {\n            if (path.at(-1) === SEPARATOR) {\n                // Collect directory entries without trailing slash\n                dirs.push(path.slice(0, -1));\n            } else {\n                // File entry - writeFile will create parent directories automatically\n                tasks.push(writeFile(join(destDir, path), unzipped[path] as Uint8Array<ArrayBuffer>));\n                // Mark all parent directories as non-empty\n                markParentDirsNonEmpty(path, nonEmptyDirs);\n            }\n        }\n\n        // Only create truly empty directories\n        for (const dir of dirs) {\n            if (!nonEmptyDirs.has(dir)) {\n                tasks.push(mkdir(join(destDir, dir)));\n            }\n        }\n\n        future.resolve(aggregateResults(tasks));\n    });\n\n    return future.promise;\n}\n\n// #endregion\n","import { fetchT } from '@happy-ts/fetch-t';\nimport { basename, join, SEPARATOR } from '@std/path/posix';\nimport { Zip, ZipDeflate, ZipPassThrough, zipSync } from 'fflate/browser';\nimport { Err, tryAsyncResult, type AsyncVoidIOResult } from 'happy-rusty';\nimport { validateAbsolutePath, validateUrl } from '../../shared/internal/mod.ts';\nimport { isFileHandle, type DirEntry, type ZipFromUrlRequestInit, type ZipLevel, type ZipOptions } from '../../shared/mod.ts';\nimport { readDir, stat, writeFile } from '../core/mod.ts';\nimport { createEmptyBodyError, createNothingToZipError, peekStream } from '../internal/mod.ts';\nimport { EMPTY_BYTES } from './helpers.ts';\n\n/**\n * Zip a file or directory using streaming compression.\n * Equivalent to `zip -r <zipFilePath> <sourcePath>`.\n *\n * This function processes files sequentially with streaming read/write,\n * minimizing memory usage. Recommended for large directories or files.\n * For better speed with small files, consider using {@link zip} instead.\n *\n * Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.\n *\n * @param sourcePath - The path to be zipped.\n * @param zipFilePath - The path to the zip file.\n * @param options - Options of zip.\n * @returns A promise that resolves to an `AsyncIOResult` indicating whether the source was successfully zipped.\n * @since 2.0.0\n * @see {@link zip} for batch version (faster for small files)\n * @see {@link unzipStream} for the reverse operation\n * @example\n * ```typescript\n * // Stream zip a large directory\n * (await zipStream('/large-documents', '/backups/documents.zip'))\n *     .inspect(() => console.log('Directory zipped successfully'));\n * ```\n */\nexport async function zipStream(sourcePath: string, zipFilePath: string, options?: ZipOptions): AsyncVoidIOResult {\n    const zipFilePathRes = validateAbsolutePath(zipFilePath);\n    if (zipFilePathRes.isErr()) return zipFilePathRes.asErr();\n    zipFilePath = zipFilePathRes.unwrap();\n\n    const statRes = await stat(sourcePath);\n    if (statRes.isErr()) return statRes.asErr();\n\n    const sourceHandle = statRes.unwrap();\n    const sourceName = basename(sourcePath);\n    const { level } = options ?? {};\n\n    if (isFileHandle(sourceHandle)) {\n        // Single file - stream read and compress\n        return streamZipFile(sourceHandle, sourceName, zipFilePath, level);\n    }\n\n    // Directory - stream compress entries directly\n    const readDirRes = await readDir(sourcePath, { recursive: true });\n    if (readDirRes.isErr()) return readDirRes.asErr();\n\n    const { preserveRoot = true } = options ?? {};\n    const entries = readDirRes.unwrap();\n\n    // Peek first entry to check if directory is empty\n    const firstRes = await tryAsyncResult(entries.next());\n    if (firstRes.isErr()) return firstRes.asErr();\n\n    const first = firstRes.unwrap();\n    if (first.done && !preserveRoot) {\n        // Empty directory with preserveRoot=false - nothing to zip\n        // Matches zip command: `zip -r archive.zip .` in empty dir returns \"Nothing to do!\"\n        return Err(createNothingToZipError());\n    }\n\n    return streamZipEntries(\n        first,\n        entries,\n        sourceName,\n        zipFilePath,\n        preserveRoot,\n        level,\n    );\n}\n\n/**\n * Zip a remote file using streaming compression.\n *\n * This function downloads and compresses the file in a streaming manner,\n * minimizing memory usage. Recommended for large remote files.\n * For small files, consider using {@link zipFromUrl} instead.\n *\n * Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.\n *\n * This API is built on `@happy-ts/fetch-t` for downloading the source.\n * `requestInit` supports `timeout`, `onProgress`, and `filename` via {@link ZipFromUrlRequestInit}.\n *\n * @param sourceUrl - The url to be zipped.\n * @param zipFilePath - The path to the zip file.\n * @param requestInit - Optional request initialization parameters.\n * @returns A promise that resolves to an `AsyncIOResult` indicating whether the source was successfully zipped.\n * @since 2.0.0\n * @see {@link zipFromUrl} for batch version (faster for small files)\n * @see {@link unzipStreamFromUrl} for the reverse operation\n * @example\n * ```typescript\n * // Stream zip a large remote file\n * (await zipStreamFromUrl('https://example.com/large-file.bin', '/backups/file.zip'))\n *     .inspect(() => console.log('Remote file zipped successfully'));\n * ```\n */\nexport async function zipStreamFromUrl(sourceUrl: string | URL, zipFilePath: string, requestInit?: ZipFromUrlRequestInit): AsyncVoidIOResult {\n    const sourceUrlRes = validateUrl(sourceUrl);\n    if (sourceUrlRes.isErr()) return sourceUrlRes.asErr();\n    sourceUrl = sourceUrlRes.unwrap();\n\n    const zipFilePathRes = validateAbsolutePath(zipFilePath);\n    if (zipFilePathRes.isErr()) return zipFilePathRes.asErr();\n    zipFilePath = zipFilePathRes.unwrap();\n\n    // Fetch as stream for true streaming\n    const fetchRes = await fetchT(sourceUrl, {\n        redirect: 'follow',\n        ...requestInit,\n        responseType: 'stream',\n        abortable: false,\n    });\n\n    if (fetchRes.isErr()) return fetchRes.asErr();\n\n    const stream = fetchRes.unwrap();\n    const { filename, keepEmptyBody = false, level } = requestInit ?? {};\n    // Use provided filename, or basename of pathname, or 'file' as fallback\n    const sourceName = filename ?? (sourceUrl.pathname !== SEPARATOR ? basename(sourceUrl.pathname) : 'file');\n\n    // Handle null stream (204/304 responses or HEAD requests)\n    if (!stream) {\n        return keepEmptyBody\n            ? zipEmptyFile(sourceName, zipFilePath)\n            : Err(createEmptyBodyError());\n    }\n\n    // Peek first chunk to check for empty body\n    const peekRes = await peekStream(stream);\n    if (peekRes.isErr()) return peekRes.asErr();\n\n    const peek = peekRes.unwrap();\n\n    if (peek.isEmpty) {\n        return keepEmptyBody\n            ? zipEmptyFile(sourceName, zipFilePath)\n            : Err(createEmptyBodyError());\n    }\n\n    return streamZipFromStream(peek.stream, sourceName, zipFilePath, level);\n}\n\n// #region Internal Functions\n\n/**\n * Create a Zip instance with callback that pipes to controller.\n */\nfunction createZip(controller: ReadableStreamDefaultController<Uint8Array<ArrayBuffer>>): Zip {\n    return new Zip((err, chunk, final) => {\n        if (err) {\n            controller.error(err);\n            return;\n        }\n\n        controller.enqueue(chunk as Uint8Array<ArrayBuffer>);\n\n        if (final) {\n            controller.close();\n        }\n    });\n}\n\n/**\n * Add an empty entry (directory or empty file) to zip.\n */\nfunction addEmptyEntry(zip: Zip, entryName: string): void {\n    const entry = new ZipPassThrough(entryName);\n    zip.add(entry);\n    entry.push(EMPTY_BYTES, true);\n}\n\n/**\n * Create a zip entry for a file, choosing the strategy based on compression level.\n *\n * - `level === 0`: use `ZipPassThrough` (store, no compression) — avoids DEFLATE overhead\n *   for already-compressed data.\n * - `level === 1..9`: use `ZipDeflate` with the given level.\n * - `level === undefined`: use `ZipDeflate` with fflate's default (6).\n *\n * Both `ZipPassThrough` and `ZipDeflate` implement `ZipInputFile`, so they share the\n * `push(chunk, final)` interface consumed by the caller.\n */\nfunction createZipEntry(entryName: string, level?: ZipLevel): ZipDeflate | ZipPassThrough {\n    if (level === 0) {\n        return new ZipPassThrough(entryName);\n    }\n    return level != null\n        ? new ZipDeflate(entryName, { level })\n        : new ZipDeflate(entryName);\n}\n\n/**\n * Stream zip a single file handle.\n */\nasync function streamZipFile(fileHandle: FileSystemFileHandle, entryName: string, zipFilePath: string, level?: ZipLevel): AsyncVoidIOResult {\n    const fileRes = await tryAsyncResult(fileHandle.getFile());\n\n    return fileRes.andThenAsync(file => {\n        return file.size === 0\n            ? zipEmptyFile(entryName, zipFilePath)\n            : streamZipFromStream(file.stream(), entryName, zipFilePath, level);\n    });\n}\n\n/**\n * Stream zip from a ReadableStream source.\n */\nfunction streamZipFromStream(\n    sourceStream: ReadableStream<Uint8Array<ArrayBuffer>>,\n    entryName: string,\n    zipFilePath: string,\n    level?: ZipLevel,\n): AsyncVoidIOResult {\n    const zipStream = new ReadableStream<Uint8Array<ArrayBuffer>>({\n        async start(controller) {\n            const zip = createZip(controller);\n            const entry = createZipEntry(entryName, level);\n            zip.add(entry);\n\n            try {\n                for await (const chunk of sourceStream) {\n                    entry.push(chunk, false);\n                }\n                entry.push(EMPTY_BYTES, true);\n                zip.end();\n            } catch (err) {\n                controller.error(err);\n            }\n        },\n    });\n\n    return writeFile(zipFilePath, zipStream);\n}\n\n/**\n * Create a zip with an empty file entry.\n *\n * This is preferred over streaming for empty files/bodies to avoid creating\n * unnecessary ReadableStream, Zip, and ZipDeflate instances.\n */\nfunction zipEmptyFile(entryName: string, zipFilePath: string): AsyncVoidIOResult {\n    const data = zipSync({\n        [entryName]: EMPTY_BYTES,\n    }) as Uint8Array<ArrayBuffer>;\n    return writeFile(zipFilePath, data);\n}\n\n/**\n * Stream zip multiple directory entries sequentially.\n */\nfunction streamZipEntries(\n    first: IteratorResult<DirEntry>,\n    rest: AsyncIterableIterator<DirEntry>,\n    sourceName: string,\n    zipFilePath: string,\n    preserveRoot: boolean,\n    level?: ZipLevel,\n): AsyncVoidIOResult {\n    const zipStream = new ReadableStream<Uint8Array<ArrayBuffer>>({\n        async start(controller) {\n            const zip = createZip(controller);\n\n            // Add root directory entry first\n            if (preserveRoot) {\n                addEmptyEntry(zip, sourceName + SEPARATOR);\n            }\n\n            // Helper to process a single entry\n            const processEntry = async ({ path, handle }: DirEntry): Promise<void> => {\n                const entryName = preserveRoot ? join(sourceName, path) : path;\n\n                // Directory entry\n                if (!isFileHandle(handle)) {\n                    addEmptyEntry(zip, entryName + SEPARATOR);\n                    return;\n                }\n\n                // File entry - stream read and compress\n                const file = await handle.getFile();\n                const entry = createZipEntry(entryName, level);\n                zip.add(entry);\n\n                for await (const chunk of file.stream()) {\n                    entry.push(chunk, false);\n                }\n                entry.push(EMPTY_BYTES, true);\n            };\n\n            try {\n                // Process peeked first entry\n                if (!first.done) {\n                    await processEntry(first.value);\n                }\n\n                // Process remaining entries\n                for await (const dirEntry of rest) {\n                    await processEntry(dirEntry);\n                }\n\n                zip.end();\n            } catch (err) {\n                controller.error(err);\n            }\n        },\n    });\n\n    return writeFile(zipFilePath, zipStream);\n}\n\n// #endregion\n","import { fetchT } from '@happy-ts/fetch-t';\nimport { basename, join, SEPARATOR } from '@std/path/posix';\nimport { zip as compress, type AsyncZippable } from 'fflate/browser';\nimport { Err, Ok, tryAsyncResult, type AsyncIOResult, type AsyncVoidIOResult, type IOResult, type VoidIOResult } from 'happy-rusty';\nimport { Future } from 'tiny-future';\nimport { readBlobBytes, readBlobBytesSync, validateAbsolutePath, validateUrl } from '../../shared/internal/mod.ts';\nimport { isFileHandle, type ZipFromUrlRequestInit, type ZipLevel, type ZipOptions } from '../../shared/mod.ts';\nimport { readDir, stat, writeFile } from '../core/mod.ts';\nimport { createEmptyBodyError, createNothingToZipError } from '../internal/mod.ts';\nimport { EMPTY_BYTES } from './helpers.ts';\n\n/**\n * Zip a file or directory and write to a zip file.\n * Equivalent to `zip -r <zipFilePath> <sourcePath>`.\n *\n * Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.\n * @param sourcePath - The path to be zipped.\n * @param zipFilePath - The path to the zip file.\n * @param options - Options of zip.\n * @returns A promise that resolves to an `AsyncIOResult` indicating whether the source was successfully zipped.\n * @since 1.6.0\n * @see {@link zipSync} for synchronous version\n * @see {@link zipStream} for streaming version (better for large files)\n * @see {@link unzip} for the reverse operation\n * @example\n * ```typescript\n * // Zip a directory to a file\n * (await zip('/documents', '/backups/documents.zip'))\n *     .inspect(() => console.log('Directory zipped successfully'));\n * ```\n */\nexport function zip(sourcePath: string, zipFilePath: string, options?: ZipOptions): AsyncVoidIOResult;\n\n/**\n * Zip a file or directory and return the zip file data.\n * Equivalent to `zip -r <zipFilePath> <sourcePath>`.\n *\n * Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.\n * @param sourcePath - The path to be zipped.\n * @param options - Options of zip.\n * @returns A promise that resolves to an `AsyncIOResult` indicating whether the source was successfully zipped.\n * @since 1.6.0\n * @see {@link zipSync} for synchronous version\n * @see {@link zipStream} for streaming version (better for large files)\n * @see {@link unzip} for the reverse operation\n * @example\n * ```typescript\n * // Zip a directory and get the data\n * (await zip('/documents'))\n *     .inspect(zipData => console.log(`Zip size: ${ zipData.byteLength } bytes`));\n * ```\n */\nexport function zip(sourcePath: string, options?: ZipOptions): AsyncIOResult<Uint8Array<ArrayBuffer>>;\nexport async function zip(sourcePath: string, zipFilePath?: string | ZipOptions, options?: ZipOptions): Promise<ZipIOResult> {\n    if (typeof zipFilePath === 'string') {\n        const zipFilePathRes = validateAbsolutePath(zipFilePath);\n        if (zipFilePathRes.isErr()) return zipFilePathRes.asErr() as ZipIOResult;\n        zipFilePath = zipFilePathRes.unwrap();\n    } else {\n        options = zipFilePath;\n        zipFilePath = undefined;\n    }\n\n    const statRes = await stat(sourcePath);\n    if (statRes.isErr()) {\n        return statRes.asErr() as ZipIOResult;\n    }\n\n    const handle = statRes.unwrap();\n    const sourceName = basename(sourcePath);\n    const zippable: AsyncZippable = {};\n\n    if (isFileHandle(handle)) {\n        // file\n        const dataRes = await getFileDataByHandle(handle);\n        if (dataRes.isErr()) {\n            return dataRes.asErr() as ZipIOResult;\n        }\n        zippable[sourceName] = dataRes.unwrap();\n    } else {\n        // directory\n        const readDirRes = await readDir(sourcePath, {\n            recursive: true,\n        });\n        if (readDirRes.isErr()) {\n            return readDirRes.asErr() as ZipIOResult;\n        }\n\n        // default to preserve root\n        const { preserveRoot = true } = options ?? {};\n        const tasks: AsyncIOResult<{\n            entryName: string;\n            data: Uint8Array<ArrayBuffer>;\n        }>[] = [];\n\n        // Add root directory entry\n        if (preserveRoot) {\n            zippable[sourceName + SEPARATOR] = EMPTY_BYTES;\n        }\n\n        try {\n            for await (const { path, handle } of readDirRes.unwrap()) {\n                const entryName = preserveRoot ? join(sourceName, path) : path;\n\n                if (isFileHandle(handle)) {\n                    // file\n                    tasks.push((async () => {\n                        const dataRes = await getFileDataByHandle(handle);\n                        return dataRes.map(data => ({\n                            entryName,\n                            data,\n                        }));\n                    })());\n                } else {\n                    // directory - add entry with trailing slash and empty content\n                    zippable[entryName + SEPARATOR] = EMPTY_BYTES;\n                }\n            }\n        } catch (e) {\n            return Err(e as Error) as ZipIOResult;\n        }\n\n        if (tasks.length > 0) {\n            const results = await Promise.all(tasks);\n            for (const res of results) {\n                if (res.isErr()) {\n                    return res.asErr() as ZipIOResult;\n                }\n                const { entryName, data } = res.unwrap();\n                zippable[entryName] = data;\n            }\n        }\n    }\n\n    // Nothing to zip - matches standard zip command behavior\n    if (Object.keys(zippable).length === 0) {\n        return Err(createNothingToZipError()) as ZipIOResult;\n    }\n\n    return zipTo(zippable, zipFilePath, options?.level);\n}\n\n/**\n * Zip a remote file and write to a zip file.\n *\n * Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.\n *\n * This API is built on `@happy-ts/fetch-t` for downloading the source.\n * `requestInit` supports `timeout`, `onProgress`, and `filename` via {@link ZipFromUrlRequestInit}.\n *\n * @param sourceUrl - The url to be zipped.\n * @param zipFilePath - The path to the zip file.\n * @param requestInit - Optional request initialization parameters.\n * @returns A promise that resolves to an `AsyncIOResult` indicating whether the source was successfully zipped.\n * @since 1.7.0\n * @see {@link zipStreamFromUrl} for streaming version (better for large files)\n * @see {@link unzipFromUrl} for the reverse operation\n * @example\n * ```typescript\n * // Zip a remote file to a local zip file\n * (await zipFromUrl('https://example.com/file.txt', '/backups/file.zip'))\n *     .inspect(() => console.log('Remote file zipped successfully'));\n * ```\n */\nexport function zipFromUrl(sourceUrl: string | URL, zipFilePath: string, requestInit?: ZipFromUrlRequestInit): AsyncVoidIOResult;\n\n/**\n * Zip a remote file and return the zip file data.\n *\n * Use [fflate](https://github.com/101arrowz/fflate) as the zip backend.\n *\n * This API is built on `@happy-ts/fetch-t` for downloading the source.\n * `requestInit` supports `timeout`, `onProgress`, and `filename` via {@link ZipFromUrlRequestInit}.\n *\n * @param sourceUrl - The url to be zipped.\n * @param requestInit - Optional request initialization parameters.\n * @returns A promise that resolves to an `AsyncIOResult` indicating whether the source was successfully zipped.\n * @since 1.7.0\n * @see {@link zipStreamFromUrl} for streaming version (better for large files)\n * @see {@link unzipFromUrl} for the reverse operation\n * @example\n * ```typescript\n * // Zip a remote file and get the data\n * (await zipFromUrl('https://example.com/file.txt'))\n *     .inspect(zipData => console.log(`Zip size: ${ zipData.byteLength } bytes`));\n * ```\n */\nexport function zipFromUrl(sourceUrl: string | URL, requestInit?: ZipFromUrlRequestInit): AsyncIOResult<Uint8Array<ArrayBuffer>>;\nexport async function zipFromUrl(sourceUrl: string | URL, zipFilePath?: string | ZipFromUrlRequestInit, requestInit?: ZipFromUrlRequestInit): Promise<ZipIOResult> {\n    const sourceUrlRes = validateUrl(sourceUrl);\n    if (sourceUrlRes.isErr()) return sourceUrlRes.asErr() as ZipIOResult;\n    sourceUrl = sourceUrlRes.unwrap();\n\n    if (typeof zipFilePath === 'string') {\n        const zipFilePathRes = validateAbsolutePath(zipFilePath);\n        if (zipFilePathRes.isErr()) return zipFilePathRes.asErr() as ZipIOResult;\n        zipFilePath = zipFilePathRes.unwrap();\n    } else {\n        requestInit = zipFilePath;\n        zipFilePath = undefined;\n    }\n\n    const fetchRes = await fetchT(sourceUrl, {\n        redirect: 'follow',\n        ...requestInit,\n        responseType: 'bytes',\n        abortable: false,\n    });\n\n    if (fetchRes.isErr()) {\n        return fetchRes.asErr() as ZipIOResult;\n    }\n\n    const bytes = fetchRes.unwrap();\n\n    const { filename, keepEmptyBody = false, level } = requestInit ?? {};\n\n    // body can be null for 204/304 responses or HEAD requests\n    if (!keepEmptyBody && bytes.byteLength === 0) {\n        return Err(createEmptyBodyError()) as ZipIOResult;\n    }\n\n    // Use provided filename, or basename of pathname, or 'file' as fallback\n    const sourceName = filename ?? (sourceUrl.pathname !== SEPARATOR ? basename(sourceUrl.pathname) : 'file');\n\n    return zipTo({\n        [sourceName]: bytes,\n    }, zipFilePath, level);\n}\n\n// #region Internal Types\n\n/**\n * Result type for zip operation.\n */\ntype ZipIOResult = IOResult<Uint8Array<ArrayBuffer>> | VoidIOResult;\n\n// #endregion\n\n// #region Internal Functions\n\n/**\n * Zip data and optionally write to the target path.\n * @param zippable - Zippable data.\n * @param zipFilePath - Target zip file path. If provided, writes to file; otherwise returns bytes.\n * @param level - Compression level (0-9). `undefined` uses fflate's default (6).\n */\nfunction zipTo(zippable: AsyncZippable, zipFilePath?: string, level?: ZipLevel): Promise<ZipIOResult> {\n    const future = new Future<ZipIOResult>();\n\n    compress(zippable, {\n        consume: true,\n        level,\n    }, async (err, bytesLike) => {\n        if (err) {\n            future.resolve(Err(err) as ZipIOResult);\n            return;\n        }\n\n        const bytes = bytesLike as Uint8Array<ArrayBuffer>;\n        // whether to write to file\n        if (zipFilePath) {\n            future.resolve(writeFile(zipFilePath, bytes));\n        } else {\n            future.resolve(Ok(bytes));\n        }\n    });\n\n    return future.promise;\n}\n\n/**\n * Reads the binary data from a file handle.\n * Uses FileReaderSync in Worker context for better performance,\n * falls back to async readBlobBytes in main thread.\n *\n * @param fileHandle - The `FileSystemFileHandle` to read from.\n * @returns A promise that resolves to an `AsyncIOResult` containing the file content as a `Uint8Array`.\n */\nfunction getFileDataByHandle(fileHandle: FileSystemFileHandle): AsyncIOResult<Uint8Array<ArrayBuffer>> {\n    return tryAsyncResult(async () => {\n        const file = await fileHandle.getFile();\n        // Use sync read in Worker context, async in main thread\n        return typeof FileReaderSync === 'function'\n            ? readBlobBytesSync(file)\n            : readBlobBytes(file);\n    });\n}\n\n// #endregion\n","import { Ok, type AsyncIOResult, type AsyncVoidIOResult } from 'happy-rusty';\nimport { validateExpiredDate } from '../shared/internal/mod.ts';\nimport { generateTempPath, isFileHandle, TMP_DIR, type TempOptions } from '../shared/mod.ts';\nimport { createFile, mkdir, remove } from './core/mod.ts';\nimport { getDirHandle, removeHandle } from './internal/mod.ts';\n\n/**\n * Creates a temporary file or directory in the `/tmp` directory.\n * Uses `crypto.randomUUID()` to generate a unique name.\n *\n * @param options - Options for creating the temporary path.\n * @returns A promise that resolves to an `AsyncIOResult` containing the created path.\n * @since 1.7.0\n * @see {@link generateTempPath} for generating paths without creating\n * @see {@link deleteTemp} for removing the entire temp directory\n * @see {@link pruneTemp} for removing expired temp files\n * @example\n * ```typescript\n * // Create a temporary file\n * (await mkTemp())\n *     .inspect(path => console.log(path)); // '/tmp/tmp-550e8400-e29b-41d4-a716-446655440000'\n *\n * // Create a temporary directory\n * await mkTemp({ isDirectory: true });\n *\n * // Create with custom basename and extension\n * await mkTemp({ basename: 'cache', extname: '.json' });\n * ```\n */\nexport async function mkTemp(options?: TempOptions): AsyncIOResult<string> {\n    const path = generateTempPath(options);\n    const { isDirectory = false } = options ?? {};\n\n    const res = await (isDirectory ? mkdir : createFile)(path);\n\n    return res.and(Ok(path));\n}\n\n/**\n * Deletes the entire temporary directory (`/tmp`) and all its contents.\n *\n * **Warning:** When writing a `ReadableStream` to a new file, `writeFile` uses a temporary file\n * in `/tmp` before moving it to the target path. Calling `deleteTemp()` during such operations\n * may cause the write to fail. Ensure no stream writes are in progress before calling this function.\n *\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 1.7.0\n * @see {@link pruneTemp} for selective cleanup\n * @see {@link remove} for general file/directory removal\n * @example\n * ```typescript\n * (await deleteTemp())\n *     .inspect(() => console.log('Temporary directory deleted'));\n * ```\n */\nexport function deleteTemp(): AsyncVoidIOResult {\n    return remove(TMP_DIR);\n}\n\n/**\n * Removes expired files from the temporary directory.\n * Only removes direct children files whose `lastModified` time is before the specified date.\n *\n * **Note:** This function only removes files directly under `/tmp`, not subdirectories or their contents.\n * Use `deleteTemp()` to remove the entire temporary directory including all nested content.\n *\n * @param expired - Files modified before this date will be deleted.\n * @returns A promise that resolves to an `AsyncVoidIOResult` indicating success or failure.\n * @since 1.7.0\n * @see {@link deleteTemp} for removing all temp files\n * @see {@link mkTemp} for creating temp files\n * @example\n * ```typescript\n * // Remove files older than 24 hours\n * const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000);\n * const result = await pruneTemp(yesterday);\n * ```\n */\nexport async function pruneTemp(expired: Date): AsyncVoidIOResult {\n    const expiredRes = validateExpiredDate(expired);\n    if (expiredRes.isErr()) return expiredRes;\n\n    // Get TMP_DIR handle to iterate and reuse for removal\n    const tmpDirHandleRes = await getDirHandle(TMP_DIR);\n\n    return tmpDirHandleRes.andTryAsync(async tmpDirHandle => {\n        const expiredTime = expired.getTime();\n        const tasks: Promise<void>[] = [];\n\n        // Only process direct children (no recursive), since mkTemp only creates top-level items\n        for await (const handle of tmpDirHandle.values()) {\n            if (!isFileHandle(handle)) {\n                continue;\n            }\n\n            tasks.push((async () => {\n                const file = await handle.getFile();\n                if (file.lastModified <= expiredTime) {\n                    return removeHandle(handle, tmpDirHandle);\n                }\n            })());\n        }\n\n        if (tasks.length > 0) {\n            await Promise.all(tasks);\n        }\n    });\n}","import { fetchT, type FetchResult, type FetchTask } from '@happy-ts/fetch-t';\nimport { extname } from '@std/path/posix';\nimport { Err, Ok } from 'happy-rusty';\nimport { validateAbsolutePath, validateUrl } from '../../shared/internal/mod.ts';\nimport type { DownloadFileTempResponse, DownloadRequestInit } from '../../shared/mod.ts';\nimport { generateTempPath } from '../../shared/mod.ts';\nimport { createFile, writeFile } from '../core/mod.ts';\nimport { createEmptyBodyError, createFailedFetchTask, peekStream } from '../internal/mod.ts';\n\n/**\n * Downloads a file from a URL and saves it to a temporary file.\n * The returned response will contain the temporary file path.\n *\n * This API is built on `@happy-ts/fetch-t`.\n * - Supports `timeout` and `onProgress` via {@link DownloadRequestInit}\n * - Supports `keepEmptyBody` to allow saving empty responses\n * - Returns an abortable {@link FetchTask}\n *\n * @param fileUrl - The URL of the file to download.\n * @param requestInit - Optional request initialization parameters.\n * @returns A task that can be aborted and contains the result of the download.\n * @since 1.0.4\n * @see {@link uploadFile} for the reverse operation\n * @see {@link unzipFromUrl} for downloading and extracting zip files\n * @example\n * ```typescript\n * // Download to a temporary file\n * const task = downloadFile('https://example.com/file.pdf');\n * (await task.result)\n *     .inspect(({ tempFilePath }) => console.log(`File downloaded to: ${ tempFilePath }`));\n * ```\n */\nexport function downloadFile(fileUrl: string | URL, requestInit?: DownloadRequestInit): FetchTask<DownloadFileTempResponse>;\n\n/**\n * Downloads a file from a URL and saves it to the specified path.\n *\n * @param fileUrl - The URL of the file to download.\n * @param filePath - The path where the downloaded file will be saved.\n * @param requestInit - Optional request initialization parameters.\n * @returns A task that can be aborted and contains the result of the download.\n * @since 1.0.4\n * @see {@link uploadFile} for the reverse operation\n * @see {@link unzipFromUrl} for downloading and extracting zip files\n * @example\n * ```typescript\n * // Download to a specific path\n * const task = downloadFile('https://example.com/file.pdf', '/downloads/file.pdf');\n * (await task.result)\n *     .inspect(() => console.log('File downloaded successfully'));\n *\n * // Abort the download\n * task.abort();\n * ```\n */\nexport function downloadFile(fileUrl: string | URL, filePath: string, requestInit?: DownloadRequestInit): FetchTask<Response>;\nexport function downloadFile(fileUrl: string | URL, filePath?: string | DownloadRequestInit, requestInit?: DownloadRequestInit): FetchTask<Response | DownloadFileTempResponse> {\n    type T = FetchResult<Response | DownloadFileTempResponse>;\n\n    const fileUrlRes = validateUrl(fileUrl);\n    if (fileUrlRes.isErr()) return createFailedFetchTask(fileUrlRes);\n    fileUrl = fileUrlRes.unwrap();\n\n    let saveToTemp = false;\n\n    if (typeof filePath === 'string') {\n        const filePathRes = validateAbsolutePath(filePath);\n        if (filePathRes.isErr()) return createFailedFetchTask(filePathRes);\n        filePath = filePathRes.unwrap();\n    } else {\n        requestInit = filePath;\n        // save to a temporary file, preserve the extension from URL\n        filePath = generateTempPath({\n            extname: extname(fileUrl.pathname),\n        });\n        saveToTemp = true;\n    }\n\n    const fetchTask = fetchT(fileUrl, {\n        redirect: 'follow',\n        ...requestInit,\n        abortable: true,\n    });\n\n    const result = (async (): T => {\n        const responseRes = await fetchTask.result;\n\n        return responseRes.andThenAsync(async rawResponse => {\n            function okResult() {\n                return Ok(\n                    saveToTemp\n                        ? {\n                            tempFilePath: filePath as string,\n                            rawResponse,\n                        } satisfies DownloadFileTempResponse\n                        : rawResponse,\n                );\n            }\n\n            // Handle empty body: return error or create empty file\n            async function handleEmptyBody() {\n                const { keepEmptyBody = false } = requestInit ?? {};\n\n                if (!keepEmptyBody) {\n                    return Err(createEmptyBodyError());\n                }\n\n                const createRes = await createFile(filePath as string);\n                return createRes.and(okResult());\n            }\n\n            // Use peek approach for true streaming while detecting empty body\n            // Note: browsers don't conform to spec (body should be null for 204/HEAD responses)\n            // See: https://developer.mozilla.org/en-US/docs/Web/API/Response/body\n            const { body } = rawResponse;\n\n            // body is null - treat as empty\n            if (!body) {\n                return handleEmptyBody();\n            }\n\n            // Peek first chunk to detect empty stream\n            const peekRes = await peekStream(body);\n            if (peekRes.isErr()) return peekRes.asErr();\n\n            const peek = peekRes.unwrap();\n            if (peek.isEmpty) {\n                return handleEmptyBody();\n            }\n\n            // True streaming write with reconstructed stream\n            const writeRes = await writeFile(filePath, peek.stream);\n\n            return writeRes.and(okResult());\n        });\n    })();\n\n    return {\n        // FetchTask.abort() accepts `any` for the reason parameter to match\n        // the native AbortController.abort(reason?: any) signature\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        abort(reason?: any): void {\n            fetchTask.abort(reason);\n        },\n\n        get aborted(): boolean {\n            return fetchTask.aborted;\n        },\n\n        get result(): T {\n            return result;\n        },\n    };\n}","import { fetchT, type FetchResult, type FetchTask } from '@happy-ts/fetch-t';\nimport { basename } from '@std/path/posix';\nimport { Err } from 'happy-rusty';\nimport { validateAbsolutePath, validateUrl } from '../../shared/internal/mod.ts';\nimport type { UploadRequestInit } from '../../shared/mod.ts';\nimport { readBlobFile } from '../ext.ts';\nimport { createAbortError, createFailedFetchTask } from '../internal/mod.ts';\n\n/**\n * Uploads a file from the specified path to a URL.\n *\n * This API is built on `@happy-ts/fetch-t`.\n * - Supports `timeout` and `onProgress` via {@link UploadRequestInit}\n * - Returns an abortable {@link FetchTask}\n *\n * @param filePath - The path of the file to upload.\n * @param uploadUrl - The URL where the file will be uploaded.\n * @param requestInit - Optional request initialization parameters.\n * @returns A task that can be aborted and contains the result of the upload.\n * @since 1.0.6\n * @see {@link downloadFile} for the reverse operation\n * @see {@link readBlobFile} for reading file as Blob before upload\n * @example\n * ```typescript\n * const task = uploadFile('/documents/report.pdf', 'https://example.com/upload');\n * (await task.result)\n *     .inspect(() => console.log('File uploaded successfully'));\n *\n * // Abort the upload\n * task.abort();\n * ```\n */\nexport function uploadFile(filePath: string, uploadUrl: string | URL, requestInit?: UploadRequestInit): FetchTask<Response> {\n    const filePathRes = validateAbsolutePath(filePath);\n    if (filePathRes.isErr()) return createFailedFetchTask(filePathRes);\n    filePath = filePathRes.unwrap();\n\n    const uploadUrlRes = validateUrl(uploadUrl);\n    if (uploadUrlRes.isErr()) return createFailedFetchTask(uploadUrlRes);\n    uploadUrl = uploadUrlRes.unwrap();\n\n    let aborted = false;\n    let fetchTask: FetchTask<Response>;\n\n    const result = (async (): FetchResult<Response> => {\n        const fileRes = await readBlobFile(filePath);\n\n        return fileRes.andThenAsync(async file => {\n            // maybe aborted\n            if (aborted) {\n                return Err(createAbortError());\n            }\n\n            const {\n                // default file name\n                filename = basename(filePath),\n                ...rest\n            } = requestInit ?? {};\n\n            const formData = new FormData();\n            formData.append(filename, file, filename);\n\n            fetchTask = fetchT(uploadUrl, {\n                method: 'POST',\n                ...rest,\n                abortable: true,\n                body: formData,\n            });\n\n            return fetchTask.result;\n        });\n    })();\n\n    return {\n        // FetchTask.abort() accepts `any` for the reason parameter to match\n        // the native AbortController.abort(reason?: any) signature\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        abort(reason?: any): void {\n            aborted = true;\n            fetchTask?.abort(reason);\n        },\n\n        get aborted(): boolean {\n            return aborted;\n        },\n\n        get result(): FetchResult<Response> {\n            return result;\n        },\n    };\n}"],"mappings":"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"}