sounds, better files
This commit is contained in:
129
src/model/FileSystem/MountedFs.ts
Normal file
129
src/model/FileSystem/MountedFs.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import { FileSystemSource, ListDirOptions, VirtualDirectory, VirtualFile } from "./types";
|
||||
import { NginxFS } from "./NginxFS";
|
||||
import { FileStashFs } from "./FileStashFs";
|
||||
import { CachePolicy, NoCacheEntryError } from "./FsCache";
|
||||
|
||||
type Config<T> = T extends FileSystemSource<any> ? ReturnType<T['getConfig']> : never;
|
||||
|
||||
const CACHE = Symbol('Cache');
|
||||
export interface Fs {
|
||||
get root(): VirtualDirectory[];
|
||||
download(file: VirtualFile): Promise<File>;
|
||||
listDir(dir: VirtualDirectory, options?: ListDirOptions): Promise<(VirtualDirectory|VirtualFile)[]>;
|
||||
}
|
||||
|
||||
export class MountedFs implements Fs {
|
||||
private filesystems: Map<string, FileSystemSource<any>> = new Map();
|
||||
public readonly name: string = 'root';
|
||||
|
||||
constructor(filesystems: (Config<NginxFS> | Config<FileStashFs>)[]) {
|
||||
for (const fsOptions of filesystems) {
|
||||
if (fsOptions.type === 'nginx') {
|
||||
this.filesystems.set(fsOptions.name, new NginxFS(fsOptions));
|
||||
} else if (fsOptions.type === 'filestash') {
|
||||
this.filesystems.set(fsOptions.name, new FileStashFs(fsOptions));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get root() {
|
||||
return [...this.filesystems.values()].map(fs => fs.root);
|
||||
}
|
||||
|
||||
download(file: VirtualFile) {
|
||||
const fs = this.filesystems.get(file.source);
|
||||
if (!fs) {
|
||||
throw new Error(`Filesystem ${file.source} not found`);
|
||||
}
|
||||
return fs.download(file);
|
||||
}
|
||||
|
||||
async listDir(dir: VirtualDirectory, options?: ListDirOptions) {
|
||||
|
||||
const fs = this.filesystems.get(dir.source);
|
||||
if (!fs) {
|
||||
throw new Error(`Filesystem ${dir.source} not found`);
|
||||
}
|
||||
const result = await fs.listDir(dir, options);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async *search(query: string, cancelToken?: AbortSignal) {
|
||||
query = query.toLocaleLowerCase();
|
||||
for (const fs of this.filesystems.values()) {
|
||||
const dirQueue = [fs.root];
|
||||
while (dirQueue.length > 0) {
|
||||
const dir = dirQueue.shift()!;
|
||||
try {
|
||||
const children = await this.listDir(dir, {cache: CachePolicy.onlyCache});
|
||||
for (const child of children) {
|
||||
if (cancelToken?.aborted) {
|
||||
return;
|
||||
}
|
||||
if (child.type === 'directory') {
|
||||
dirQueue.push(child);
|
||||
} else if (child.name.toLocaleLowerCase().includes(query)) {
|
||||
yield child;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
if (!(err instanceof NoCacheEntryError)) {
|
||||
console.warn(`Failed to list directory ${dir.path.join('/')}`, err);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async *buildIndex() {
|
||||
let counter = 0;
|
||||
for (const fs of this.filesystems.values()) {
|
||||
const dirQueue = [fs.root];
|
||||
while (dirQueue.length > 0) {
|
||||
const dir = dirQueue.shift()!;
|
||||
for (const child of await this.listDir(dir)) {
|
||||
if (child.type === 'directory') {
|
||||
dirQueue.push(child);
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
yield counter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// export class SearchableFilesystem implements Fs {
|
||||
// public allFiles: VirtualFile[] = [];
|
||||
|
||||
// constructor(private fs: MountedFs) {}
|
||||
|
||||
// async precacheDir(dir: VirtualDirectory) {
|
||||
// for (const child of await this.fs.listDir(dir, {cache: CachePolicy.useCache})) {
|
||||
// if (child.type === 'file') {
|
||||
// this.allFiles.push(child);
|
||||
// } else {
|
||||
// await this.precacheDir(child as VirtualDirectory);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// async search(query: string) {
|
||||
// await Promise.all(this.fs.root.map((root) => this.precacheDir(root)));
|
||||
// }
|
||||
|
||||
// get root() {
|
||||
// return this.fs.root;
|
||||
// }
|
||||
|
||||
// async listDir(dir: VirtualDirectory) {
|
||||
// return this.fs.listDir(dir);
|
||||
// }
|
||||
|
||||
// async download(file: VirtualFile) {
|
||||
// return this.fs.download(file);
|
||||
// }
|
||||
// }
|
||||
Reference in New Issue
Block a user