1 | import {Directory, DirectoryContent, File, ShallowDirectory} from "./model";
|
2 | import {Correlation, EventEmitter, FileSystem, fileSystemEventNames, FileSystemReadSync} from "./api";
|
3 | import {EventsManager} from "./events-manager";
|
4 |
|
5 | export type Options = {
|
6 | delayEvents: number;
|
7 | correlationWindow: number;
|
8 | };
|
9 |
|
10 | export class NoFeedbackEventsFileSystem implements FileSystem {
|
11 | public baseUrl: string;
|
12 | private readonly eventsManager = new EventsManager({delay: this.options.delayEvents});
|
13 | public readonly events: EventEmitter = this.eventsManager.events;
|
14 | private readonly correlateOnce = new Set<Correlation>();
|
15 | private readonly correlateByWindow = new Set<Correlation>();
|
16 |
|
17 | constructor(private fs: FileSystem, private options: Options = {delayEvents: 1, correlationWindow: 10000}) {
|
18 | this.baseUrl = fs.baseUrl;
|
19 | this.eventsManager.addEventHandler({
|
20 | types: fileSystemEventNames,
|
21 | filter: (e) => {
|
22 | return !!e.correlation && (this.correlateByWindow.has(e.correlation) || this.correlateOnce.delete(e.correlation));
|
23 | },
|
24 | apply: () => {
|
25 | },
|
26 | });
|
27 | const emit = this.eventsManager.emit.bind(this.eventsManager);
|
28 | fileSystemEventNames.forEach(type => this.fs.events.on(type, emit));
|
29 | }
|
30 |
|
31 | async saveFile(fullPath: string, newContent: string): Promise<Correlation> {
|
32 | return this.registerCorrelation(await this.fs.saveFile(fullPath, newContent), false);
|
33 | }
|
34 |
|
35 | async deleteFile(fullPath: string): Promise<Correlation> {
|
36 | return this.registerCorrelation(await this.fs.deleteFile(fullPath), true);
|
37 | }
|
38 |
|
39 | async deleteDirectory(fullPath: string, recursive?: boolean): Promise<Correlation> {
|
40 | return this.registerCorrelation(await this.fs.deleteDirectory(fullPath, recursive), !recursive);
|
41 | }
|
42 |
|
43 | async ensureDirectory(fullPath: string): Promise<Correlation> {
|
44 | return this.registerCorrelation(await this.fs.ensureDirectory(fullPath), false);
|
45 | }
|
46 |
|
47 | loadTextFile(fullPath: string): Promise<string> {
|
48 | return this.fs.loadTextFile(fullPath);
|
49 | }
|
50 |
|
51 | loadDirectoryTree(fullPath?: string): Promise<Directory> {
|
52 | return this.fs.loadDirectoryTree(fullPath);
|
53 | }
|
54 |
|
55 | loadDirectoryChildren(fullPath: string): Promise<(File | ShallowDirectory)[]> {
|
56 | return this.fs.loadDirectoryChildren(fullPath);
|
57 | }
|
58 |
|
59 | protected registerCorrelation(correlation: Correlation, once: boolean) {
|
60 | const targetSet = once ? this.correlateOnce : this.correlateByWindow;
|
61 | targetSet.add(correlation);
|
62 | setTimeout(() => targetSet.delete(correlation), this.options.correlationWindow);
|
63 | return correlation;
|
64 | }
|
65 | }
|
66 |
|
67 | export class NoFeedbackEventsFileSystemSync extends NoFeedbackEventsFileSystem implements FileSystemReadSync {
|
68 |
|
69 | constructor(private syncFs: FileSystemReadSync) {
|
70 | super(syncFs);
|
71 | }
|
72 |
|
73 | loadTextFileSync(fullPath: string): string {
|
74 | return this.syncFs.loadTextFileSync(fullPath);
|
75 | }
|
76 |
|
77 | loadDirectoryTreeSync(fullPath?: string | undefined): Directory {
|
78 | return this.syncFs.loadDirectoryTreeSync(fullPath);
|
79 | }
|
80 |
|
81 | loadDirectoryChildrenSync(fullPath: string): (File | ShallowDirectory)[] {
|
82 | return this.syncFs.loadDirectoryChildrenSync(fullPath);
|
83 | }
|
84 |
|
85 | loadDirectoryContentSync(fullPath: string = ''): DirectoryContent {
|
86 | return this.syncFs.loadDirectoryContentSync(fullPath);
|
87 | }
|
88 | }
|