/* eslint-disable import/no-relative-parent-imports */
import { getLock } from "p-lock";
import { createManifest, defaultManifestPath, defaultNamesPath, ensureStoreFiles, readManifest, readNamesFile, writeManifest, writeNamesFile } from "../backend/store.js";
import { fetchChangesSince, fetchReleasePackage, seedNamesFromReleaseAssets } from "./registry.js";
const syncLock = getLock();
function uniqueSortedNames(names) {
    const values = Array.from(names).filter((name) => name.length > 0);
    values.sort();
    return values.filter((name, index) => index === 0 || name !== values[index - 1]);
}
/**
 * Restores the local store from the latest published GitHub release.
 */
export async function bootstrapNames(options = {}) {
    const namesPath = options.namesPath ?? defaultNamesPath;
    const manifestPath = options.manifestPath ?? defaultManifestPath;
    const seeded = await fetchReleasePackage(options.release ?? "latest");
    const names = uniqueSortedNames(seeded.names);
    const manifest = createManifest(names, seeded.since);
    await Promise.all([
        writeNamesFile(namesPath, names),
        writeManifest(manifestPath, manifest)
    ]);
    return {
        version: seeded.version,
        since: seeded.since,
        count: names.length
    };
}
/**
 * Synchronizes the local store files with the npm replication feed.
 */
export async function syncNames(options = {}) {
    const namesPath = options.namesPath ?? defaultNamesPath;
    const manifestPath = options.manifestPath ?? defaultManifestPath;
    return syncLock().then(async (release) => {
        try {
            await ensureStoreFiles(namesPath, manifestPath);
            let names = await readNamesFile(namesPath);
            let manifest = await readManifest(manifestPath);
            if (names.length === 0) {
                const seeded = await seedNamesFromReleaseAssets({
                    onProgress: options.onProgress
                });
                names = uniqueSortedNames(seeded.names);
                manifest = createManifest(names, seeded.since);
            }
            const changes = await fetchChangesSince(manifest.since, {
                onProgress: options.onProgress
            });
            const set = new Set(names);
            for (const name of changes.deleted) {
                set.delete(name);
            }
            for (const name of changes.created) {
                set.add(name);
            }
            const nextNames = uniqueSortedNames(set);
            const nextManifest = createManifest(nextNames, changes.since);
            await Promise.all([
                writeNamesFile(namesPath, nextNames),
                writeManifest(manifestPath, nextManifest)
            ]);
            return {
                since: changes.since,
                count: nextNames.length,
                added: changes.created.size,
                removed: changes.deleted.size,
                processedChanges: changes.processedChanges
            };
        }
        finally {
            release();
        }
    });
}
//# sourceMappingURL=index.js.map