Files
XCDesktop/api/watcher/watcher.ts
2026-03-08 01:34:54 +08:00

44 lines
1.4 KiB
TypeScript

import chokidar, { FSWatcher } from 'chokidar';
import path from 'path';
import { NOTEBOOK_ROOT } from '../config/paths.js';
import { eventBus } from '../events/eventBus.js';
import { logger } from '../utils/logger.js';
import { toPosixPath } from '../../shared/utils/path.js';
let watcher: FSWatcher | null = null;
export const startWatcher = (): void => {
if (watcher) return;
logger.info(`Starting file watcher for: ${NOTEBOOK_ROOT}`);
watcher = chokidar.watch(NOTEBOOK_ROOT, {
ignored: /(^|[\/\\])\../,
persistent: true,
ignoreInitial: true,
});
const broadcast = (event: string, changedPath: string) => {
const rel = path.relative(NOTEBOOK_ROOT, changedPath);
if (!rel || rel.startsWith('..') || path.isAbsolute(rel)) return;
logger.info(`File event: ${event} - ${rel}`);
eventBus.broadcast({ event, path: toPosixPath(rel) });
};
watcher
.on('add', (p) => broadcast('add', p))
.on('change', (p) => broadcast('change', p))
.on('unlink', (p) => broadcast('unlink', p))
.on('addDir', (p) => broadcast('addDir', p))
.on('unlinkDir', (p) => broadcast('unlinkDir', p))
.on('ready', () => logger.info('File watcher ready'))
.on('error', (err) => logger.error('File watcher error:', err));
};
export const stopWatcher = async (): Promise<void> => {
if (watcher) {
await watcher.close();
watcher = null;
}
};