UNPKG

@push.rocks/smartchok

Version:

A smart wrapper for chokidar 4.x with glob pattern support and enhanced features.

176 lines 13.9 kB
import * as plugins from './smartchok.plugins.js'; import { Stringmap } from '@push.rocks/lik'; /** * Smartchok allows easy wathcing of files */ export class Smartchok { /** * constructor of class smartchok */ constructor(watchArrayArg) { this.watchStringmap = new Stringmap(); this.status = 'idle'; this.globPatterns = []; this.globMatchers = new Map(); this.watchingDeferred = plugins.smartpromise.defer(); // used to run things when watcher is initialized this.eventObservablemap = new plugins.smartrx.Observablemap(); // register one observable per event this.watchStringmap.addStringArray(watchArrayArg); } getGlobBase(globPattern) { // Characters that mark the beginning of a glob pattern const globChars = ['*', '?', '[', ']', '{', '}']; // Find the index of the first glob character const firstGlobCharIndex = globPattern.split('').findIndex((char) => globChars.includes(char)); // If no glob characters are found, return the entire string if (firstGlobCharIndex === -1) { return globPattern; } // Extract the substring up to the first glob character const basePathPortion = globPattern.substring(0, firstGlobCharIndex); // Find the last slash before the glob pattern starts const lastSlashIndex = basePathPortion.lastIndexOf('/'); // If there is no slash, return the basePathPortion as is if (lastSlashIndex === -1) { return basePathPortion; } // Return the base path up to and including the last slash return basePathPortion.substring(0, lastSlashIndex + 1); } /** * adds files to the list of watched files */ add(pathArrayArg) { this.watchStringmap.addStringArray(pathArrayArg); } /** * removes files from the list of watched files */ remove(pathArg) { this.watchStringmap.removeString(pathArg); } /** * gets an observable for a certain event */ getObservableFor(fsEvent) { const done = plugins.smartpromise.defer(); this.watchingDeferred.promise.then(() => { const eventObservable = this.eventObservablemap.getSubjectForEmitterEvent(this.watcher, fsEvent); done.resolve(eventObservable); }); return done.promise; } /** * starts the watcher * @returns Promise<void> */ start() { const done = plugins.smartpromise.defer(); this.status = 'starting'; // Store original glob patterns and create matchers this.globPatterns = this.watchStringmap.getStringArray(); const basePaths = new Set(); this.globPatterns.forEach((pattern) => { const basePath = this.getGlobBase(pattern); basePaths.add(basePath); // Create a picomatch matcher for each glob pattern const matcher = plugins.picomatch(pattern, { dot: true, basename: false }); this.globMatchers.set(pattern, matcher); }); // Convert Set to Array for chokidar const watchPaths = Array.from(basePaths); console.log('Base paths to watch:', watchPaths); this.watcher = plugins.chokidar.watch(watchPaths, { persistent: true, ignoreInitial: false, followSymlinks: false, depth: 4, awaitWriteFinish: { stabilityThreshold: 300, pollInterval: 100 }, ignored: (path, stats) => { // Don't filter during initialization - let chokidar watch everything // We'll filter events as they come in return false; } }); // Set up event handlers with glob filtering const fileEvents = ['add', 'addDir', 'change', 'unlink', 'unlinkDir']; // Handle file events fileEvents.forEach(eventName => { this.watcher.on(eventName, (path, stats) => { // Only emit event if the path matches our glob patterns if (this.shouldWatchPath(path)) { this.eventObservablemap.getSubjectForEmitterEvent(this.watcher, eventName) .next([path, stats]); } }); }); // Handle error events this.watcher.on('error', (error) => { this.eventObservablemap.getSubjectForEmitterEvent(this.watcher, 'error') .next([error, undefined]); }); // Handle raw events this.watcher.on('raw', (eventType, path, details) => { if (this.shouldWatchPath(path)) { this.eventObservablemap.getSubjectForEmitterEvent(this.watcher, 'raw') .next([path, undefined]); } }); this.watcher.on('ready', () => { this.status = 'watching'; this.watchingDeferred.resolve(); done.resolve(); }); return done.promise; } /** * stop the watcher process if watching */ async stop() { const closeWatcher = async () => { await this.watcher.close(); }; if (this.status === 'watching') { console.log('closing while watching'); await closeWatcher(); } else if (this.status === 'starting') { await this.watchingDeferred.promise; await closeWatcher(); } } /** * Checks if a path should be watched based on glob patterns */ shouldWatchPath(filePath) { // Normalize the path - remove leading ./ if present let normalizedPath = filePath.replace(/\\/g, '/'); if (normalizedPath.startsWith('./')) { normalizedPath = normalizedPath.substring(2); } // Check if the path matches any of our glob patterns for (const [pattern, matcher] of this.globMatchers) { // Also normalize the pattern for comparison let normalizedPattern = pattern; if (normalizedPattern.startsWith('./')) { normalizedPattern = normalizedPattern.substring(2); } // Try matching with both the original pattern and normalized if (matcher(normalizedPath) || matcher(filePath)) { return true; } // Also try matching without the leading path const withoutLeading = 'test/' + normalizedPath.split('test/').slice(1).join('test/'); if (matcher(withoutLeading)) { return true; } } return false; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRjaG9rLmNsYXNzZXMuc21hcnRjaG9rLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRjaG9rLmNsYXNzZXMuc21hcnRjaG9rLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sd0JBQXdCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBYTVDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFNBQVM7SUFTcEI7O09BRUc7SUFDSCxZQUFZLGFBQXVCO1FBWDVCLG1CQUFjLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUNqQyxXQUFNLEdBQXFCLE1BQU0sQ0FBQztRQUVqQyxpQkFBWSxHQUFhLEVBQUUsQ0FBQztRQUM1QixpQkFBWSxHQUEyQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ2pFLHFCQUFnQixHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFRLENBQUMsQ0FBQyxpREFBaUQ7UUFDeEcsdUJBQWtCLEdBQUcsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsb0NBQW9DO1FBTXBHLElBQUksQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFTyxXQUFXLENBQUMsV0FBbUI7UUFDckMsdURBQXVEO1FBQ3ZELE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUVqRCw2Q0FBNkM7UUFDN0MsTUFBTSxrQkFBa0IsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBRS9GLDREQUE0RDtRQUM1RCxJ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