smartchok/ts/smartchok.classes.smartchok.ts

128 lines
3.5 KiB
TypeScript
Raw Normal View History

2024-01-28 00:18:39 +00:00
import * as plugins from './smartchok.plugins.js';
import { Stringmap } from '@push.rocks/lik';
2017-06-30 16:05:55 +00:00
2018-02-28 23:08:08 +00:00
export type TSmartchokStatus = 'idle' | 'starting' | 'watching';
export type TFsEvent =
| 'add'
| 'addDir'
| 'change'
| 'error'
| 'unlink'
| 'unlinkDir'
| 'ready'
| 'raw';
2017-06-30 16:05:55 +00:00
/**
* Smartchok allows easy wathcing of files
*/
export class Smartchok {
2019-09-29 14:35:12 +00:00
public watchStringmap = new Stringmap();
public status: TSmartchokStatus = 'idle';
2024-01-28 00:18:39 +00:00
private watcher: plugins.watcher;
2018-10-10 15:06:40 +00:00
private watchingDeferred = plugins.smartpromise.defer<void>(); // used to run things when watcher is initialized
2018-02-28 23:08:08 +00:00
private eventObservablemap = new plugins.smartrx.Observablemap(); // register one observable per event
2017-06-30 16:05:55 +00:00
/**
* constructor of class smartchok
*/
2024-01-28 00:18:39 +00:00
constructor(watchArrayArg: string[]) {
2018-02-28 23:08:08 +00:00
this.watchStringmap.addStringArray(watchArrayArg);
2024-01-28 00:18:39 +00:00
}
private getGlobBase(globPattern: string) {
// 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);
2017-06-30 16:05:55 +00:00
}
/**
* adds files to the list of watched files
*/
2019-09-29 14:35:12 +00:00
public add(pathArrayArg: string[]) {
2018-02-28 23:08:08 +00:00
this.watchStringmap.addStringArray(pathArrayArg);
2017-06-30 16:05:55 +00:00
}
/**
* removes files from the list of watched files
*/
2019-09-29 14:35:12 +00:00
public remove(pathArg: string) {
2018-02-28 23:08:08 +00:00
this.watchStringmap.removeString(pathArg);
2017-06-30 16:05:55 +00:00
}
/**
* gets an observable for a certain event
*/
2024-01-28 00:18:39 +00:00
public getObservableFor(
fsEvent: TFsEvent
): Promise<plugins.smartrx.rxjs.Observable<[string, plugins.fs.Stats]>> {
2019-09-29 14:35:12 +00:00
const done = plugins.smartpromise.defer<plugins.smartrx.rxjs.Observable<any>>();
2017-06-30 16:05:55 +00:00
this.watchingDeferred.promise.then(() => {
2024-01-28 00:18:39 +00:00
const eventObservable = this.eventObservablemap.getSubjectForEmitterEvent(
2018-02-28 23:08:08 +00:00
this.watcher,
fsEvent
);
done.resolve(eventObservable);
});
return done.promise;
2017-06-30 16:05:55 +00:00
}
/**
* starts the watcher
* @returns Promise<void>
*/
2019-09-29 14:35:12 +00:00
public start(): Promise<void> {
const done = plugins.smartpromise.defer<void>();
2018-02-28 23:08:08 +00:00
this.status = 'starting';
2024-01-28 00:18:39 +00:00
this.watcher = new plugins.watcher(
2024-01-28 16:25:47 +00:00
this.watchStringmap.getStringArray().map((string) => this.getGlobBase(string)),
{
depth: 20,
recursive: true,
}
2018-02-28 23:08:08 +00:00
);
2017-06-30 16:05:55 +00:00
this.watcher.on('ready', () => {
2018-02-28 23:08:08 +00:00
this.status = 'watching';
this.watchingDeferred.resolve();
done.resolve();
});
return done.promise;
2017-06-30 16:05:55 +00:00
}
/**
* stop the watcher process if watching
*/
2021-11-29 19:26:59 +00:00
public async stop() {
const closeWatcher = async () => {
await this.watcher.close();
2018-02-28 23:08:08 +00:00
};
2017-06-30 16:05:55 +00:00
if (this.status === 'watching') {
2018-02-28 23:08:08 +00:00
console.log('closing while watching');
2021-11-29 19:26:59 +00:00
await closeWatcher();
2017-06-30 16:05:55 +00:00
} else if (this.status === 'starting') {
2021-11-29 19:26:59 +00:00
await this.watchingDeferred.promise;
await closeWatcher();
2017-06-30 16:05:55 +00:00
}
}
}