poku
Version:
🐷 Poku makes testing easy for Node.js, Bun, Deno, and you at the same time.
86 lines (85 loc) • 2.95 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.watch = exports.Watcher = void 0;
const node_fs_1 = require("fs");
const promises_1 = require("fs/promises");
const node_path_1 = require("path");
const list_files_js_1 = require("../modules/helpers/list-files.js");
class Watcher {
constructor(rootDir, callback) {
this.files = [];
this.fileWatchers = new Map();
this.dirWatchers = new Map();
this.rootDir = rootDir;
this.callback = callback;
}
watchFile(filePath) {
if (this.fileWatchers.has(filePath))
return;
const watcher = (0, node_fs_1.watch)(filePath, (eventType) => this.callback(filePath, eventType));
this.fileWatchers.set(filePath, watcher);
}
unwatchFiles() {
for (const [filePath, watcher] of this.fileWatchers) {
watcher.close();
this.fileWatchers.delete(filePath);
}
}
watchFiles(filePaths) {
this.unwatchFiles();
for (const filePath of filePaths)
this.watchFile(filePath);
}
async watchDirectory(dir) {
if (this.dirWatchers.has(dir))
return;
const watcher = (0, node_fs_1.watch)(dir, async (_, filename) => {
if (filename) {
const fullPath = (0, node_path_1.join)(dir, filename);
this.files = await (0, list_files_js_1.listFiles)(this.rootDir);
this.watchFiles(this.files);
try {
const stats = await (0, promises_1.stat)(fullPath);
if (stats.isDirectory())
await this.watchDirectory(fullPath);
}
catch { }
}
});
this.dirWatchers.set(dir, watcher);
const entries = await (0, promises_1.readdir)(dir, { withFileTypes: true });
for (const entry of entries) {
if (!entry.isDirectory())
continue;
const fullPath = (0, node_path_1.join)(dir, entry.name);
await this.watchDirectory(fullPath);
}
}
async start() {
const stats = await (0, promises_1.stat)(this.rootDir);
if (stats.isDirectory()) {
this.files = await (0, list_files_js_1.listFiles)(this.rootDir);
this.watchFiles(this.files);
await this.watchDirectory(this.rootDir);
return;
}
this.watchFile(this.rootDir);
}
stop() {
this.unwatchFiles();
this.unwatchDirectories();
}
unwatchDirectories() {
for (const [dirPath, watcher] of this.dirWatchers) {
watcher.close();
this.dirWatchers.delete(dirPath);
}
}
}
exports.Watcher = Watcher;
const watch = async (path, callback) => {
const watcher = new Watcher(path, callback);
await watcher.start();
return watcher;
};
exports.watch = watch;