Files
2020-05-19 11:51:04 -04:00

97 lines
3.4 KiB
JavaScript

/// @ts-check
var os = require("os")
var fs = require("fs");
var path = require("path");
var crypto = require('crypto');
// In theory, msgpack should be more performant than JSON serialization,
// but I haven't noted that in my tests and it also caused some problems.
// For now, msgpack code is kept in tryLoadCache and trySaveCache
// var msgpack = require("msgpack-lite");
// From https://stackoverflow.com/a/32197381/3922220
var deleteFolderRecursive = function(path) {
if( fs.existsSync(path) ) {
fs.readdirSync(path).forEach(function(file,index){
var curPath = path + "/" + file;
if(fs.lstatSync(curPath).isDirectory()) { // recurse
deleteFolderRecursive(curPath);
} else { // delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(path);
}
};
function getCachePath(fileName) {
var fableTempDir = path.join(os.tmpdir(), "fable");
if (!fs.existsSync(fableTempDir)){
fs.mkdirSync(fableTempDir);
}
var hash = crypto.createHash('md5').update(fileName).digest('hex');
return path.join(fableTempDir, hash);
}
exports.clearCache = function () {
var fableTempDir = path.join(os.tmpdir(), "fable");
deleteFolderRecursive(fableTempDir);
}
function CachedFile(fileContents) {
var json = JSON.parse(fileContents);
this.code = json.code;
this.map = json.map;
}
exports.CachedFile = CachedFile;
exports.tryLoadCache = function (extraOpts, fileName) {
if (!extraOpts || !extraOpts.useCache || path.extname(fileName) !== ".fs") {
return Promise.resolve(null);
}
return new Promise(resolve => {
try {
var cachePath = getCachePath(fileName);
if (fs.existsSync(cachePath)) {
var sourcemtime = fs.statSync(fileName).mtime;
var cachemtime = fs.statSync(cachePath).mtime;
if (sourcemtime < cachemtime) {
var fileContents = fs.readFileSync(cachePath, "utf8").toString();
resolve(new CachedFile(fileContents));
// var readStream = fs.createReadStream(cachePath);
// var decodeStream = msgpack.createDecodeStream();
// readStream.pipe(decodeStream).on("data", data => { resolve(data) });
return;
}
}
}
catch (err) {
var relPath = path.relative(process.cwd(), fileName);
console.log("fable: Couldn't load " + relPath + " from cache. " + String(err));
// Do nothing, just fall through
}
resolve(null);
});
}
// This may need some kind of lock when building projects in parallel which share files
// and both try to cache the same file at the same time
exports.trySaveCache = function (extraOpts, fileName, data) {
try {
if (extraOpts && extraOpts.useCache && extraOpts.useCache !== "readonly") {
fs.writeFileSync(getCachePath(fileName), JSON.stringify(data), {encoding: "utf8"});
// var writeStream = fs.createWriteStream(getCachePath(fileName));
// var encodeStream = msgpack.createEncodeStream();
// encodeStream.pipe(data);
// encodeStream.write(babelParsed);
// encodeStream.end();
}
}
catch (err) {
var relPath = path.relative(process.cwd(), fileName);
console.log("fable: Couldn't save " + relPath + " to cache. " + String(err));
}
}