CoolFace
Datasetpublic

basant307/AI_Governance_Project

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes48downloads
index.js805 linesDownload Raw Back to chokidar
1"use strict";2Object.defineProperty(exports, "__esModule", { value: true });3exports.FSWatcher = exports.WatchHelper = void 0;4exports.watch = watch;5/*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */6const fs_1 = require("fs");7const promises_1 = require("fs/promises");8const events_1 = require("events");9const sysPath = require("path");10const readdirp_1 = require("readdirp");11const handler_js_1 = require("./handler.js");12const SLASH = '/';13const SLASH_SLASH = '//';14const ONE_DOT = '.';15const TWO_DOTS = '..';16const STRING_TYPE = 'string';17const BACK_SLASH_RE = /\\/g;18const DOUBLE_SLASH_RE = /\/\//;19const DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;20const REPLACER_RE = /^\.[/\\]/;21function arrify(item) {22    return Array.isArray(item) ? item : [item];23}24const isMatcherObject = (matcher) => typeof matcher === 'object' && matcher !== null && !(matcher instanceof RegExp);25function createPattern(matcher) {26    if (typeof matcher === 'function')27        return matcher;28    if (typeof matcher === 'string')29        return (string) => matcher === string;30    if (matcher instanceof RegExp)31        return (string) => matcher.test(string);32    if (typeof matcher === 'object' && matcher !== null) {33        return (string) => {34            if (matcher.path === string)35                return true;36            if (matcher.recursive) {37                const relative = sysPath.relative(matcher.path, string);38                if (!relative) {39                    return false;40                }41                return !relative.startsWith('..') && !sysPath.isAbsolute(relative);42            }43            return false;44        };45    }46    return () => false;47}48function normalizePath(path) {49    if (typeof path !== 'string')50        throw new Error('string expected');51    path = sysPath.normalize(path);52    path = path.replace(/\\/g, '/');53    let prepend = false;54    if (path.startsWith('//'))55        prepend = true;56    const DOUBLE_SLASH_RE = /\/\//;57    while (path.match(DOUBLE_SLASH_RE))58        path = path.replace(DOUBLE_SLASH_RE, '/');59    if (prepend)60        path = '/' + path;61    return path;62}63function matchPatterns(patterns, testString, stats) {64    const path = normalizePath(testString);65    for (let index = 0; index < patterns.length; index++) {66        const pattern = patterns[index];67        if (pattern(path, stats)) {68            return true;69        }70    }71    return false;72}73function anymatch(matchers, testString) {74    if (matchers == null) {75        throw new TypeError('anymatch: specify first argument');76    }77    // Early cache for matchers.78    const matchersArray = arrify(matchers);79    const patterns = matchersArray.map((matcher) => createPattern(matcher));80    if (testString == null) {81        return (testString, stats) => {82            return matchPatterns(patterns, testString, stats);83        };84    }85    return matchPatterns(patterns, testString);86}87const unifyPaths = (paths_) => {88    const paths = arrify(paths_).flat();89    if (!paths.every((p) => typeof p === STRING_TYPE)) {90        throw new TypeError(`Non-string provided as watch path: ${paths}`);91    }92    return paths.map(normalizePathToUnix);93};94// If SLASH_SLASH occurs at the beginning of path, it is not replaced95//     because "//StoragePC/DrivePool/Movies" is a valid network path96const toUnix = (string) => {97    let str = string.replace(BACK_SLASH_RE, SLASH);98    let prepend = false;99    if (str.startsWith(SLASH_SLASH)) {100        prepend = true;101    }102    while (str.match(DOUBLE_SLASH_RE)) {103        str = str.replace(DOUBLE_SLASH_RE, SLASH);104    }105    if (prepend) {106        str = SLASH + str;107    }108    return str;109};110// Our version of upath.normalize111// TODO: this is not equal to path-normalize module - investigate why112const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path)));113// TODO: refactor114const normalizeIgnored = (cwd = '') => (path) => {115    if (typeof path === 'string') {116        return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path));117    }118    else {119        return path;120    }121};122const getAbsolutePath = (path, cwd) => {123    if (sysPath.isAbsolute(path)) {124        return path;125    }126    return sysPath.join(cwd, path);127};128const EMPTY_SET = Object.freeze(new Set());129/**130 * Directory entry.131 */132class DirEntry {133    constructor(dir, removeWatcher) {134        this.path = dir;135        this._removeWatcher = removeWatcher;136        this.items = new Set();137    }138    add(item) {139        const { items } = this;140        if (!items)141            return;142        if (item !== ONE_DOT && item !== TWO_DOTS)143            items.add(item);144    }145    async remove(item) {146        const { items } = this;147        if (!items)148            return;149        items.delete(item);150        if (items.size > 0)151            return;152        const dir = this.path;153        try {154            await (0, promises_1.readdir)(dir);155        }156        catch (err) {157            if (this._removeWatcher) {158                this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir));159            }160        }161    }162    has(item) {163        const { items } = this;164        if (!items)165            return;166        return items.has(item);167    }168    getChildren() {169        const { items } = this;170        if (!items)171            return [];172        return [...items.values()];173    }174    dispose() {175        this.items.clear();176        this.path = '';177        this._removeWatcher = handler_js_1.EMPTY_FN;178        this.items = EMPTY_SET;179        Object.freeze(this);180    }181}182const STAT_METHOD_F = 'stat';183const STAT_METHOD_L = 'lstat';184class WatchHelper {185    constructor(path, follow, fsw) {186        this.fsw = fsw;187        const watchPath = path;188        this.path = path = path.replace(REPLACER_RE, '');189        this.watchPath = watchPath;190        this.fullWatchPath = sysPath.resolve(watchPath);191        this.dirParts = [];192        this.dirParts.forEach((parts) => {193            if (parts.length > 1)194                parts.pop();195        });196        this.followSymlinks = follow;197        this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;198    }199    entryPath(entry) {200        return sysPath.join(this.watchPath, sysPath.relative(this.watchPath, entry.fullPath));201    }202    filterPath(entry) {203        const { stats } = entry;204        if (stats && stats.isSymbolicLink())205            return this.filterDir(entry);206        const resolvedPath = this.entryPath(entry);207        // TODO: what if stats is undefined? remove !208        return this.fsw._isntIgnored(resolvedPath, stats) && this.fsw._hasReadPermissions(stats);209    }210    filterDir(entry) {211        return this.fsw._isntIgnored(this.entryPath(entry), entry.stats);212    }213}214exports.WatchHelper = WatchHelper;215/**216 * Watches files & directories for changes. Emitted events:217 * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`218 *219 *     new FSWatcher()220 *       .add(directories)221 *       .on('add', path => log('File', path, 'was added'))222 */223class FSWatcher extends events_1.EventEmitter {224    // Not indenting methods for history sake; for now.225    constructor(_opts = {}) {226        super();227        this.closed = false;228        this._closers = new Map();229        this._ignoredPaths = new Set();230        this._throttled = new Map();231        this._streams = new Set();232        this._symlinkPaths = new Map();233        this._watched = new Map();234        this._pendingWrites = new Map();235        this._pendingUnlinks = new Map();236        this._readyCount = 0;237        this._readyEmitted = false;238        const awf = _opts.awaitWriteFinish;239        const DEF_AWF = { stabilityThreshold: 2000, pollInterval: 100 };240        const opts = {241            // Defaults242            persistent: true,243            ignoreInitial: false,244            ignorePermissionErrors: false,245            interval: 100,246            binaryInterval: 300,247            followSymlinks: true,248            usePolling: false,249            // useAsync: false,250            atomic: true, // NOTE: overwritten later (depends on usePolling)251            ..._opts,252            // Change format253            ignored: _opts.ignored ? arrify(_opts.ignored) : arrify([]),254            awaitWriteFinish: awf === true ? DEF_AWF : typeof awf === 'object' ? { ...DEF_AWF, ...awf } : false,255        };256        // Always default to polling on IBM i because fs.watch() is not available on IBM i.257        if (handler_js_1.isIBMi)258            opts.usePolling = true;259        // Editor atomic write normalization enabled by default with fs.watch260        if (opts.atomic === undefined)261            opts.atomic = !opts.usePolling;262        // opts.atomic = typeof _opts.atomic === 'number' ? _opts.atomic : 100;263        // Global override. Useful for developers, who need to force polling for all264        // instances of chokidar, regardless of usage / dependency depth265        const envPoll = process.env.CHOKIDAR_USEPOLLING;266        if (envPoll !== undefined) {267            const envLower = envPoll.toLowerCase();268            if (envLower === 'false' || envLower === '0')269                opts.usePolling = false;270            else if (envLower === 'true' || envLower === '1')271                opts.usePolling = true;272            else273                opts.usePolling = !!envLower;274        }275        const envInterval = process.env.CHOKIDAR_INTERVAL;276        if (envInterval)277            opts.interval = Number.parseInt(envInterval, 10);278        // This is done to emit ready only once, but each 'add' will increase that?279        let readyCalls = 0;280        this._emitReady = () => {281            readyCalls++;282            if (readyCalls >= this._readyCount) {283                this._emitReady = handler_js_1.EMPTY_FN;284                this._readyEmitted = true;285                // use process.nextTick to allow time for listener to be bound286                process.nextTick(() => this.emit(handler_js_1.EVENTS.READY));287            }288        };289        this._emitRaw = (...args) => this.emit(handler_js_1.EVENTS.RAW, ...args);290        this._boundRemove = this._remove.bind(this);291        this.options = opts;292        this._nodeFsHandler = new handler_js_1.NodeFsHandler(this);293        // You’re frozen when your heart’s not open.294        Object.freeze(opts);295    }296    _addIgnoredPath(matcher) {297        if (isMatcherObject(matcher)) {298            // return early if we already have a deeply equal matcher object299            for (const ignored of this._ignoredPaths) {300                if (isMatcherObject(ignored) &&301                    ignored.path === matcher.path &&302                    ignored.recursive === matcher.recursive) {303                    return;304                }305            }306        }307        this._ignoredPaths.add(matcher);308    }309    _removeIgnoredPath(matcher) {310        this._ignoredPaths.delete(matcher);311        // now find any matcher objects with the matcher as path312        if (typeof matcher === 'string') {313            for (const ignored of this._ignoredPaths) {314                // TODO (43081j): make this more efficient.315                // probably just make a `this._ignoredDirectories` or some316                // such thing.317                if (isMatcherObject(ignored) && ignored.path === matcher) {318                    this._ignoredPaths.delete(ignored);319                }320            }321        }322    }323    // Public methods324    /**325     * Adds paths to be watched on an existing FSWatcher instance.326     * @param paths_ file or file list. Other arguments are unused327     */328    add(paths_, _origAdd, _internal) {329        const { cwd } = this.options;330        this.closed = false;331        this._closePromise = undefined;332        let paths = unifyPaths(paths_);333        if (cwd) {334            paths = paths.map((path) => {335                const absPath = getAbsolutePath(path, cwd);336                // Check `path` instead of `absPath` because the cwd portion can't be a glob337                return absPath;338            });339        }340        paths.forEach((path) => {341            this._removeIgnoredPath(path);342        });343        this._userIgnored = undefined;344        if (!this._readyCount)345            this._readyCount = 0;346        this._readyCount += paths.length;347        Promise.all(paths.map(async (path) => {348            const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, undefined, 0, _origAdd);349            if (res)350                this._emitReady();351            return res;352        })).then((results) => {353            if (this.closed)354                return;355            results.forEach((item) => {356                if (item)357                    this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item));358            });359        });360        return this;361    }362    /**363     * Close watchers or start ignoring events from specified paths.364     */365    unwatch(paths_) {366        if (this.closed)367            return this;368        const paths = unifyPaths(paths_);369        const { cwd } = this.options;370        paths.forEach((path) => {371            // convert to absolute path unless relative path already matches372            if (!sysPath.isAbsolute(path) && !this._closers.has(path)) {373                if (cwd)374                    path = sysPath.join(cwd, path);375                path = sysPath.resolve(path);376            }377            this._closePath(path);378            this._addIgnoredPath(path);379            if (this._watched.has(path)) {380                this._addIgnoredPath({381                    path,382                    recursive: true,383                });384            }385            // reset the cached userIgnored anymatch fn386            // to make ignoredPaths changes effective387            this._userIgnored = undefined;388        });389        return this;390    }391    /**392     * Close watchers and remove all listeners from watched paths.393     */394    close() {395        if (this._closePromise) {396            return this._closePromise;397        }398        this.closed = true;399        // Memory management.400        this.removeAllListeners();401        const closers = [];402        this._closers.forEach((closerList) => closerList.forEach((closer) => {403            const promise = closer();404            if (promise instanceof Promise)405                closers.push(promise);406        }));407        this._streams.forEach((stream) => stream.destroy());408        this._userIgnored = undefined;409        this._readyCount = 0;410        this._readyEmitted = false;411        this._watched.forEach((dirent) => dirent.dispose());412        this._closers.clear();413        this._watched.clear();414        this._streams.clear();415        this._symlinkPaths.clear();416        this._throttled.clear();417        this._closePromise = closers.length418            ? Promise.all(closers).then(() => undefined)419            : Promise.resolve();420        return this._closePromise;421    }422    /**423     * Expose list of watched paths424     * @returns for chaining425     */426    getWatched() {427        const watchList = {};428        this._watched.forEach((entry, dir) => {429            const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir;430            const index = key || ONE_DOT;431            watchList[index] = entry.getChildren().sort();432        });433        return watchList;434    }435    emitWithAll(event, args) {436        this.emit(event, ...args);437        if (event !== handler_js_1.EVENTS.ERROR)438            this.emit(handler_js_1.EVENTS.ALL, event, ...args);439    }440    // Common helpers441    // --------------442    /**443     * Normalize and emit events.444     * Calling _emit DOES NOT MEAN emit() would be called!445     * @param event Type of event446     * @param path File or directory path447     * @param stats arguments to be passed with event448     * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag449     */450    async _emit(event, path, stats) {451        if (this.closed)452            return;453        const opts = this.options;454        if (handler_js_1.isWindows)455            path = sysPath.normalize(path);456        if (opts.cwd)457            path = sysPath.relative(opts.cwd, path);458        const args = [path];459        if (stats != null)460            args.push(stats);461        const awf = opts.awaitWriteFinish;462        let pw;463        if (awf && (pw = this._pendingWrites.get(path))) {464            pw.lastChange = new Date();465            return this;466        }467        if (opts.atomic) {468            if (event === handler_js_1.EVENTS.UNLINK) {469                this._pendingUnlinks.set(path, [event, ...args]);470                setTimeout(() => {471                    this._pendingUnlinks.forEach((entry, path) => {472                        this.emit(...entry);473                        this.emit(handler_js_1.EVENTS.ALL, ...entry);474                        this._pendingUnlinks.delete(path);475                    });476                }, typeof opts.atomic === 'number' ? opts.atomic : 100);477                return this;478            }479            if (event === handler_js_1.EVENTS.ADD && this._pendingUnlinks.has(path)) {480                event = handler_js_1.EVENTS.CHANGE;481                this._pendingUnlinks.delete(path);482            }483        }484        if (awf && (event === handler_js_1.EVENTS.ADD || event === handler_js_1.EVENTS.CHANGE) && this._readyEmitted) {485            const awfEmit = (err, stats) => {486                if (err) {487                    event = handler_js_1.EVENTS.ERROR;488                    args[0] = err;489                    this.emitWithAll(event, args);490                }491                else if (stats) {492                    // if stats doesn't exist the file must have been deleted493                    if (args.length > 1) {494                        args[1] = stats;495                    }496                    else {497                        args.push(stats);498                    }499                    this.emitWithAll(event, args);500                }501            };502            this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit);503            return this;504        }505        if (event === handler_js_1.EVENTS.CHANGE) {506            const isThrottled = !this._throttle(handler_js_1.EVENTS.CHANGE, path, 50);507            if (isThrottled)508                return this;509        }510        if (opts.alwaysStat &&511            stats === undefined &&512            (event === handler_js_1.EVENTS.ADD || event === handler_js_1.EVENTS.ADD_DIR || event === handler_js_1.EVENTS.CHANGE)) {513            const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path;514            let stats;515            try {516                stats = await (0, promises_1.stat)(fullPath);517            }518            catch (err) {519                // do nothing520            }521            // Suppress event when fs_stat fails, to avoid sending undefined 'stat'522            if (!stats || this.closed)523                return;524            args.push(stats);525        }526        this.emitWithAll(event, args);527        return this;528    }529    /**530     * Common handler for errors531     * @returns The error if defined, otherwise the value of the FSWatcher instance's `closed` flag532     */533    _handleError(error) {534        const code = error && error.code;535        if (error &&536            code !== 'ENOENT' &&537            code !== 'ENOTDIR' &&538            (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES'))) {539            this.emit(handler_js_1.EVENTS.ERROR, error);540        }541        return error || this.closed;542    }543    /**544     * Helper utility for throttling545     * @param actionType type being throttled546     * @param path being acted upon547     * @param timeout duration of time to suppress duplicate actions548     * @returns tracking object or false if action should be suppressed549     */550    _throttle(actionType, path, timeout) {551        if (!this._throttled.has(actionType)) {552            this._throttled.set(actionType, new Map());553        }554        const action = this._throttled.get(actionType);555        if (!action)556            throw new Error('invalid throttle');557        const actionPath = action.get(path);558        if (actionPath) {559            actionPath.count++;560            return false;561        }562        // eslint-disable-next-line prefer-const563        let timeoutObject;564        const clear = () => {565            const item = action.get(path);566            const count = item ? item.count : 0;567            action.delete(path);568            clearTimeout(timeoutObject);569            if (item)570                clearTimeout(item.timeoutObject);571            return count;572        };573        timeoutObject = setTimeout(clear, timeout);574        const thr = { timeoutObject, clear, count: 0 };575        action.set(path, thr);576        return thr;577    }578    _incrReadyCount() {579        return this._readyCount++;580    }581    /**582     * Awaits write operation to finish.583     * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback.584     * @param path being acted upon585     * @param threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished586     * @param event587     * @param awfEmit Callback to be called when ready for event to be emitted.588     */589    _awaitWriteFinish(path, threshold, event, awfEmit) {590        const awf = this.options.awaitWriteFinish;591        if (typeof awf !== 'object')592            return;593        const pollInterval = awf.pollInterval;594        let timeoutHandler;595        let fullPath = path;596        if (this.options.cwd && !sysPath.isAbsolute(path)) {597            fullPath = sysPath.join(this.options.cwd, path);598        }599        const now = new Date();600        const writes = this._pendingWrites;601        function awaitWriteFinishFn(prevStat) {602            (0, fs_1.stat)(fullPath, (err, curStat) => {603                if (err || !writes.has(path)) {604                    if (err && err.code !== 'ENOENT')605                        awfEmit(err);606                    return;607                }608                const now = Number(new Date());609                if (prevStat && curStat.size !== prevStat.size) {610                    writes.get(path).lastChange = now;611                }612                const pw = writes.get(path);613                const df = now - pw.lastChange;614                if (df >= threshold) {615                    writes.delete(path);616                    awfEmit(undefined, curStat);617                }618                else {619                    timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);620                }621            });622        }623        if (!writes.has(path)) {624            writes.set(path, {625                lastChange: now,626                cancelWait: () => {627                    writes.delete(path);628                    clearTimeout(timeoutHandler);629                    return event;630                },631            });632            timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);633        }634    }635    /**636     * Determines whether user has asked to ignore this path.637     */638    _isIgnored(path, stats) {639        if (this.options.atomic && DOT_RE.test(path))640            return true;641        if (!this._userIgnored) {642            const { cwd } = this.options;643            const ign = this.options.ignored;644            const ignored = (ign || []).map(normalizeIgnored(cwd));645            const ignoredPaths = [...this._ignoredPaths];646            const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];647            this._userIgnored = anymatch(list, undefined);648        }649        return this._userIgnored(path, stats);650    }651    _isntIgnored(path, stat) {652        return !this._isIgnored(path, stat);653    }654    /**655     * Provides a set of common helpers and properties relating to symlink handling.656     * @param path file or directory pattern being watched657     */658    _getWatchHelpers(path) {659        return new WatchHelper(path, this.options.followSymlinks, this);660    }661    // Directory helpers662    // -----------------663    /**664     * Provides directory tracking objects665     * @param directory path of the directory666     */667    _getWatchedDir(directory) {668        const dir = sysPath.resolve(directory);669        if (!this._watched.has(dir))670            this._watched.set(dir, new DirEntry(dir, this._boundRemove));671        return this._watched.get(dir);672    }673    // File helpers674    // ------------675    /**676     * Check for read permissions: https://stackoverflow.com/a/11781404/1358405677     */678    _hasReadPermissions(stats) {679        if (this.options.ignorePermissionErrors)680            return true;681        return Boolean(Number(stats.mode) & 0o400);682    }683    /**684     * Handles emitting unlink events for685     * files and directories, and via recursion, for686     * files and directories within directories that are unlinked687     * @param directory within which the following item is located688     * @param item      base path of item/directory689     */690    _remove(directory, item, isDirectory) {691        // if what is being deleted is a directory, get that directory's paths692        // for recursive deleting and cleaning of watched object693        // if it is not a directory, nestedDirectoryChildren will be empty array694        const path = sysPath.join(directory, item);695        const fullPath = sysPath.resolve(path);696        isDirectory =697            isDirectory != null ? isDirectory : this._watched.has(path) || this._watched.has(fullPath);698        // prevent duplicate handling in case of arriving here nearly simultaneously699        // via multiple paths (such as _handleFile and _handleDir)700        if (!this._throttle('remove', path, 100))701            return;702        // if the only watched file is removed, watch for its return703        if (!isDirectory && this._watched.size === 1) {704            this.add(directory, item, true);705        }706        // This will create a new entry in the watched object in either case707        // so we got to do the directory check beforehand708        const wp = this._getWatchedDir(path);709        const nestedDirectoryChildren = wp.getChildren();710        // Recursively remove children directories / files.711        nestedDirectoryChildren.forEach((nested) => this._remove(path, nested));712        // Check if item was on the watched list and remove it713        const parent = this._getWatchedDir(directory);714        const wasTracked = parent.has(item);715        parent.remove(item);716        // Fixes issue #1042 -> Relative paths were detected and added as symlinks717        // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612),718        // but never removed from the map in case the path was deleted.719        // This leads to an incorrect state if the path was recreated:720        // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553721        if (this._symlinkPaths.has(fullPath)) {722            this._symlinkPaths.delete(fullPath);723        }724        // If we wait for this file to be fully written, cancel the wait.725        let relPath = path;726        if (this.options.cwd)727            relPath = sysPath.relative(this.options.cwd, path);728        if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {729            const event = this._pendingWrites.get(relPath).cancelWait();730            if (event === handler_js_1.EVENTS.ADD)731                return;732        }733        // The Entry will either be a directory that just got removed734        // or a bogus entry to a file, in either case we have to remove it735        this._watched.delete(path);736        this._watched.delete(fullPath);737        const eventName = isDirectory ? handler_js_1.EVENTS.UNLINK_DIR : handler_js_1.EVENTS.UNLINK;738        if (wasTracked && !this._isIgnored(path))739            this._emit(eventName, path);740        // Avoid conflicts if we later create another file with the same name741        this._closePath(path);742    }743    /**744     * Closes all watchers for a path745     */746    _closePath(path) {747        this._closeFile(path);748        const dir = sysPath.dirname(path);749        this._getWatchedDir(dir).remove(sysPath.basename(path));750    }751    /**752     * Closes only file-specific watchers753     */754    _closeFile(path) {755        const closers = this._closers.get(path);756        if (!closers)757            return;758        closers.forEach((closer) => closer());759        this._closers.delete(path);760    }761    _addPathCloser(path, closer) {762        if (!closer)763            return;764        let list = this._closers.get(path);765        if (!list) {766            list = [];767            this._closers.set(path, list);768        }769        list.push(closer);770    }771    _readdirp(root, opts) {772        if (this.closed)773            return;774        const options = { type: handler_js_1.EVENTS.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 };775        let stream = (0, readdirp_1.readdirp)(root, options);776        this._streams.add(stream);777        stream.once(handler_js_1.STR_CLOSE, () => {778            stream = undefined;779        });780        stream.once(handler_js_1.STR_END, () => {781            if (stream) {782                this._streams.delete(stream);783                stream = undefined;784            }785        });786        return stream;787    }788}789exports.FSWatcher = FSWatcher;790/**791 * Instantiates watcher with paths to be tracked.792 * @param paths file / directory paths793 * @param options opts, such as `atomic`, `awaitWriteFinish`, `ignored`, and others794 * @returns an instance of FSWatcher for chaining.795 * @example796 * const watcher = watch('.').on('all', (event, path) => { console.log(event, path); });797 * watch('.', { atomic: true, awaitWriteFinish: true, ignored: (f, stats) => stats?.isFile() && !f.endsWith('.js') })798 */799function watch(paths, options = {}) {800    const watcher = new FSWatcher(options);801    watcher.add(paths);802    return watcher;803}804exports.default = { watch, FSWatcher };805 
basant307/AI_Governance_Project · CoolFace