greybel-js
Version:
Transpiler/Interpreter for GreyScript. (GreyHack)
101 lines (100 loc) • 3.04 kB
JavaScript
import { crlf, LF } from 'crlf-normalize';
import fs from 'fs/promises';
import path from 'path';
export class FileSystemManager {
basename(file) {
return path.basename(file);
}
dirname(file) {
return path.dirname(file);
}
resolve(file) {
return path.resolve(file);
}
async tryToGet(target, unsafe = false) {
try {
return await fs.readFile(target, 'utf-8');
}
catch (err) {
if (!unsafe)
console.error(err);
}
return null;
}
async tryToDecode(target, unsafe = false) {
const out = await this.tryToGet(target, unsafe);
if (out != null) {
return crlf(out, LF);
}
return null;
}
async checkFileExists(target) {
return fs
.access(target, fs.constants.F_OK)
.then(() => true)
.catch(() => false);
}
async findExistingPath(mainPath, ...altPaths) {
if (await this.checkFileExists(mainPath))
return mainPath;
if (altPaths.length === 0) {
return null;
}
try {
const altItemPath = await Promise.any(altPaths.map(async (path) => {
if (await this.checkFileExists(path))
return path;
throw new Error('Alternative path could not resolve');
}));
if (altItemPath != null) {
return altItemPath;
}
return null;
}
catch (err) {
return null;
}
}
}
export class FileSystemManagerWithCache extends FileSystemManager {
fileContentCache;
fileExistsCache;
pathResolveCache;
constructor() {
super();
this.fileContentCache = new Map();
this.pathResolveCache = new Map();
this.fileExistsCache = new Map();
}
async checkFileExists(target) {
const key = target.toString();
const cachedExists = this.fileExistsCache.get(key);
if (cachedExists !== undefined) {
return cachedExists;
}
const exists = await super.checkFileExists(target);
this.fileExistsCache.set(key, exists);
return exists;
}
async tryToGet(target, unsafe = false) {
const key = target;
const result = this.fileContentCache.get(key);
if (result !== undefined) {
return result;
}
const content = await super.tryToGet(target, unsafe);
this.fileContentCache.set(key, content);
return content;
}
async findExistingPath(mainPath, ...altPaths) {
const key = mainPath;
const cachedPath = this.pathResolveCache.get(key);
if (cachedPath !== undefined) {
return cachedPath;
}
const result = await super.findExistingPath(mainPath, ...altPaths);
this.pathResolveCache.set(key, result);
return result;
}
}
export const GlobalFileSystemManager = new FileSystemManager();