97 lines
3.4 KiB
JavaScript
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));
|
|
}
|
|
}
|