import { watch } from 'chokidar';
const DEFAULT_IGNORED = [
    /(^|[\\/])\.git([\\/]|$)/,
    /(^|[\\/])node_modules([\\/]|$)/,
    /(^|[\\/])\.nanocoder([\\/]|$)/,
];
export class FileWatcherSource {
    router;
    options;
    watcher = null;
    constructor(router, options) {
        this.router = router;
        this.options = options;
    }
    async start() {
        if (this.watcher)
            return;
        const watchFn = this.options._watchFn ?? watch;
        // Watch '.' with cwd set to root so chokidar emits paths relative
        // to root — no manual relativization needed in emit().
        const watcher = watchFn('.', {
            cwd: this.options.root,
            ignored: this.options.ignored ?? DEFAULT_IGNORED,
            ignoreInitial: true,
            persistent: true,
            usePolling: this.options.usePolling ?? false,
            interval: this.options.pollingInterval ?? 50,
            binaryInterval: this.options.pollingInterval ?? 50,
        });
        watcher.on('add', file => this.emit(file, 'add'));
        watcher.on('change', file => this.emit(file, 'change'));
        watcher.on('unlink', file => this.emit(file, 'unlink'));
        try {
            await new Promise((resolve, reject) => {
                watcher.once('ready', () => resolve());
                watcher.once('error', reject);
            });
            this.watcher = watcher;
        }
        catch (error) {
            await watcher.close();
            throw error;
        }
    }
    async stop() {
        if (!this.watcher)
            return;
        const w = this.watcher;
        this.watcher = null;
        await w.close();
    }
    emit(file, eventKind) {
        void this.router.emit({
            kind: 'file.changed',
            payload: { file, eventKind },
            at: Date.now(),
        });
    }
}
//# sourceMappingURL=file-watcher.js.map