import fs from "node:fs/promises";
import { removeFromDisk } from "./disk-cache.js";
import { createMemoryCache } from "./memory-cache.js";
import { createRevalidator } from "./background-revalidator.js";
import { resolveData } from "./cache-orchestrator.js";
function createDefaultFs() {
    return {
        readFile: (path, encoding) => fs.readFile(path, encoding),
        writeFile: (path, data, options) => fs.writeFile(path, data, options),
        rename: (from, to) => fs.rename(from, to),
        mkdir: (path, options) => fs.mkdir(path, options).then(() => { }),
        unlink: (path) => fs.unlink(path),
        realpath: (path) => fs.realpath(path),
    };
}
export function createCachedResource(bundledData, config, deps) {
    const diskFs = deps?.fs ?? createDefaultFs();
    const memoryCache = createMemoryCache({
        max: 100,
        ttl: config.staleTtl,
    });
    const revalidator = createRevalidator();
    return {
        get(options) {
            return resolveData(bundledData, config, {
                memoryCache,
                fs: diskFs,
                fetch: deps?.fetch,
                revalidator,
            }, options).then(cloneCachedData);
        },
        refresh() {
            return this.get({ forceRefresh: true });
        },
        async clear() {
            await revalidator.waitForRevalidation(config.cacheName);
            memoryCache.clear();
            await removeFromDisk(config, { fs: diskFs });
        },
        stats() {
            return {
                memoryCacheSize: memoryCache.size,
                memoryCacheMax: memoryCache.max,
                cacheDir: config.cacheDir,
            };
        },
    };
}
function cloneCachedData(cached) {
    return structuredClone(cached);
}
