
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3b70f126-e106-5fcf-b9e9-6db05d7e44e2")}catch(e){}}();
import { randomUUID } from "node:crypto";
import { chmod, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
import { dirname, join } from "node:path";
import * as lockfile from "proper-lockfile";
const DEFAULT_LOCK_STALE_MS = 10_000;
const DEFAULT_LOCK_RETRIES = {
    retries: 200,
    factor: 1,
    minTimeout: 25,
    maxTimeout: 50,
    randomize: false,
};
function createLockOptions(request, lockfilePath) {
    const options = {
        stale: request.staleMs ?? DEFAULT_LOCK_STALE_MS,
        retries: request.retries ?? DEFAULT_LOCK_RETRIES,
        realpath: false,
        lockfilePath,
    };
    if (typeof request.onCompromised === "function") {
        options.onCompromised = request.onCompromised;
    }
    return options;
}
async function readFileIfExists(path) {
    try {
        return await readFile(path, "utf8");
    }
    catch (error) {
        if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
            return null;
        }
        throw error;
    }
}
export class LockedFileSystem {
    async normalizeLockRequest(request) {
        if (request.type === "directory") {
            await mkdir(request.path, { recursive: true });
            const lockfilePath = request.lockfilePath ?? join(request.path, request.lockfileName ?? ".lock");
            return {
                path: request.path,
                options: createLockOptions(request, lockfilePath),
                sortKey: lockfilePath,
            };
        }
        await mkdir(dirname(request.path), { recursive: true });
        const lockfilePath = request.lockfilePath ?? `${request.path}.lock`;
        return {
            path: request.path,
            options: createLockOptions(request, lockfilePath),
            sortKey: lockfilePath,
        };
    }
    async withLock(request, operation) {
        return await this.withLocks([request], operation);
    }
    async withLocks(requests, operation) {
        const normalizedRequests = await Promise.all(requests.map(async (request) => await this.normalizeLockRequest(request)));
        const orderedRequests = normalizedRequests
            .slice()
            .sort((left, right) => left.sortKey.localeCompare(right.sortKey));
        const releases = [];
        try {
            for (const request of orderedRequests) {
                releases.push(await lockfile.lock(request.path, request.options));
            }
            return await operation();
        }
        finally {
            for (const release of releases.reverse()) {
                await release();
            }
        }
    }
    async writeTextFileAtomic(path, content, options = {}) {
        const lockRequest = options.lock === undefined
            ? {
                path,
                type: "file",
            }
            : options.lock;
        const writeOperation = async () => {
            const existingContent = await readFileIfExists(path);
            if (existingContent === content) {
                if (options.executable) {
                    await chmod(path, 0o755);
                }
                return;
            }
            await mkdir(dirname(path), { recursive: true });
            const tempPath = `${path}.tmp.${process.pid}.${Date.now()}.${randomUUID()}`;
            await writeFile(tempPath, content, "utf8");
            await rename(tempPath, path);
            if (options.executable) {
                await chmod(path, 0o755);
            }
        };
        if (lockRequest) {
            await this.withLock(lockRequest, writeOperation);
            return;
        }
        await writeOperation();
    }
    async writeJsonFileAtomic(path, payload, options = {}) {
        await this.writeTextFileAtomic(path, JSON.stringify(payload, null, 2), options);
    }
    async removePath(path, options) {
        await this.withLock(options.lock, async () => {
            await rm(path, {
                recursive: options.recursive,
                force: options.force,
            });
        });
    }
}
export const lockedFileSystem = new LockedFileSystem();
//# sourceMappingURL=locked-file-system.js.map
//# debugId=3b70f126-e106-5fcf-b9e9-6db05d7e44e2
