Pulls the local-client-cli and obsidian-plugin changes from asch/fix-everything onto a fresh branch off main.
93 lines
2.8 KiB
TypeScript
93 lines
2.8 KiB
TypeScript
import Watcher from "watcher";
|
|
import * as path from "path";
|
|
import type { SyncClient, RelativePath } from "sync-client";
|
|
import { toUnixPath, matchesGlob } from "./path-utils";
|
|
|
|
export class FileWatcher {
|
|
private watcher: Watcher | undefined;
|
|
private isRunning = false;
|
|
private readonly ignorePatterns: string[];
|
|
|
|
public constructor(
|
|
private readonly basePath: string,
|
|
private readonly client: SyncClient,
|
|
ignorePatterns: string[] = []
|
|
) {
|
|
this.ignorePatterns = ignorePatterns;
|
|
}
|
|
|
|
public start(): void {
|
|
if (this.isRunning) {
|
|
return;
|
|
}
|
|
|
|
this.isRunning = true;
|
|
|
|
this.watcher = new Watcher(this.basePath, {
|
|
recursive: true,
|
|
renameDetection: true,
|
|
renameTimeout: 125,
|
|
ignoreInitial: true,
|
|
ignore: (filePath: string): boolean => this.shouldIgnore(filePath)
|
|
});
|
|
|
|
this.watcher.on("add", (filePath: string) => {
|
|
this.handleCreate(this.toRelativePath(filePath));
|
|
});
|
|
|
|
this.watcher.on("change", (filePath: string) => {
|
|
this.handleChange(this.toRelativePath(filePath));
|
|
});
|
|
|
|
this.watcher.on("unlink", (filePath: string) => {
|
|
this.handleDelete(this.toRelativePath(filePath));
|
|
});
|
|
|
|
this.watcher.on("rename", (oldPath: string, newPath: string) => {
|
|
this.handleRename(
|
|
this.toRelativePath(oldPath),
|
|
this.toRelativePath(newPath)
|
|
);
|
|
});
|
|
|
|
this.client.logger.info("File watcher started");
|
|
}
|
|
|
|
public stop(): void {
|
|
if (this.watcher !== undefined) {
|
|
this.watcher.close();
|
|
this.watcher = undefined;
|
|
}
|
|
this.isRunning = false;
|
|
this.client.logger.info("File watcher stopped");
|
|
}
|
|
|
|
private shouldIgnore(filePath: string): boolean {
|
|
const rel = toUnixPath(path.relative(this.basePath, filePath));
|
|
return this.ignorePatterns.some((pattern) => matchesGlob(rel, pattern));
|
|
}
|
|
|
|
private handleCreate(relativePath: RelativePath): void {
|
|
this.client.syncLocallyCreatedFile(relativePath);
|
|
}
|
|
|
|
private handleChange(relativePath: RelativePath): void {
|
|
this.client.syncLocallyUpdatedFile({ relativePath });
|
|
}
|
|
|
|
private handleDelete(relativePath: RelativePath): void {
|
|
this.client.syncLocallyDeletedFile(relativePath);
|
|
}
|
|
|
|
private handleRename(oldPath: RelativePath, newPath: RelativePath): void {
|
|
this.client.logger.info(`File renamed: ${oldPath} -> ${newPath}`);
|
|
this.client.syncLocallyUpdatedFile({
|
|
oldPath,
|
|
relativePath: newPath
|
|
});
|
|
}
|
|
|
|
private toRelativePath(absolutePath: string): RelativePath {
|
|
return toUnixPath(path.relative(this.basePath, absolutePath));
|
|
}
|
|
}
|