@push.rocks/smartchok
Version:
A smart wrapper for chokidar 4.x with glob pattern support and enhanced features.
176 lines • 13.9 kB
JavaScript
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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