import { readFileSync, existsSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const EMPTY_SHARD = Object.freeze({});
function defaultDataDir() {
    return resolve(dirname(fileURLToPath(import.meta.url)), '..', 'data');
}
/**
 * Lazily loads per-suffix postcode shards from disk and caches them in memory.
 * One instance per validator; safe to share across threads (read-only).
 */
export class ShardLoader {
    dataDir;
    cache = new Map();
    manifestCache;
    constructor(dataDir) {
        this.dataDir = dataDir ?? defaultDataDir();
    }
    /** Returns the map of postcodes for the given two-letter suffix. */
    loadShard(suffix) {
        const key = suffix.toUpperCase();
        const cached = this.cache.get(key);
        if (cached)
            return cached;
        const path = resolve(this.dataDir, `${key}.json`);
        if (!existsSync(path)) {
            this.cache.set(key, EMPTY_SHARD);
            return EMPTY_SHARD;
        }
        const raw = readFileSync(path, 'utf8');
        const parsed = JSON.parse(raw);
        this.cache.set(key, parsed);
        return parsed;
    }
    /** Returns the dataset manifest, cached after first read. */
    getManifest() {
        if (this.manifestCache !== undefined)
            return this.manifestCache;
        const path = resolve(this.dataDir, 'manifest.json');
        if (!existsSync(path)) {
            this.manifestCache = null;
            return null;
        }
        this.manifestCache = JSON.parse(readFileSync(path, 'utf8'));
        return this.manifestCache;
    }
    /** Drops all cached shards. Useful in long-running processes under memory pressure. */
    clearCache() {
        this.cache.clear();
        this.manifestCache = undefined;
    }
}
//# sourceMappingURL=shardLoader.js.map