This repository has been archived on 2024-07-27. You can view files and clone it, but cannot push or open issues or pull requests.
keksAccountGUI/node_modulesOLD/cache-loader/dist/index.js

225 lines
5.4 KiB
JavaScript
Raw Permalink Normal View History

2019-08-11 18:48:02 +00:00
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = loader;
exports.pitch = pitch;
/* eslint-disable
import/order
*/
const fs = require('fs');
const path = require('path');
const normalizePath = require('normalize-path');
const async = require('neo-async');
const crypto = require('crypto');
const mkdirp = require('mkdirp');
const {
getOptions
} = require('loader-utils');
const validateOptions = require('schema-utils');
const pkg = require('../package.json');
const env = process.env.NODE_ENV || 'development';
const schema = require('./options.json');
const defaults = {
cacheContext: '',
cacheDirectory: path.resolve('.cache-loader'),
cacheIdentifier: `cache-loader:${pkg.version} ${env}`,
cacheKey,
read,
write
};
function pathWithCacheContext(cacheContext, originalPath) {
if (!cacheContext) {
return originalPath;
}
if (originalPath.includes(cacheContext)) {
return originalPath.split('!').map(subPath => normalizePath(path.relative(cacheContext, subPath))).join('!');
}
return originalPath.split('!').map(subPath => normalizePath(path.resolve(cacheContext, subPath))).join('!');
}
function loader(...args) {
const options = Object.assign({}, defaults, getOptions(this));
validateOptions(schema, options, 'Cache Loader');
const {
write: writeFn
} = options;
const callback = this.async();
const {
data
} = this;
const dependencies = this.getDependencies().concat(this.loaders.map(l => l.path));
const contextDependencies = this.getContextDependencies(); // Should the file get cached?
let cache = true; // this.fs can be undefined
// e.g when using the thread-loader
// fallback to the fs module
const FS = this.fs || fs;
const toDepDetails = (dep, mapCallback) => {
FS.stat(dep, (err, stats) => {
if (err) {
mapCallback(err);
return;
}
const mtime = stats.mtime.getTime();
if (mtime / 1000 >= Math.floor(data.startTime / 1000)) {
// Don't trust mtime.
// File was changed while compiling
// or it could be an inaccurate filesystem.
cache = false;
}
mapCallback(null, {
path: pathWithCacheContext(options.cacheContext, dep),
mtime
});
});
};
async.parallel([cb => async.mapLimit(dependencies, 20, toDepDetails, cb), cb => async.mapLimit(contextDependencies, 20, toDepDetails, cb)], (err, taskResults) => {
if (err) {
callback(null, ...args);
return;
}
if (!cache) {
callback(null, ...args);
return;
}
const [deps, contextDeps] = taskResults;
writeFn(data.cacheKey, {
remainingRequest: data.remainingRequest,
dependencies: deps,
contextDependencies: contextDeps,
result: args
}, () => {
// ignore errors here
callback(null, ...args);
});
});
}
function pitch(remainingRequest, prevRequest, dataInput) {
const options = Object.assign({}, defaults, getOptions(this));
validateOptions(schema, options, 'Cache Loader (Pitch)');
const {
read: readFn,
cacheContext,
cacheKey: cacheKeyFn
} = options;
const callback = this.async();
const data = dataInput;
data.remainingRequest = pathWithCacheContext(cacheContext, remainingRequest);
data.cacheKey = cacheKeyFn(options, data.remainingRequest);
readFn(data.cacheKey, (readErr, cacheData) => {
if (readErr) {
callback();
return;
}
if (cacheData.remainingRequest !== data.remainingRequest) {
// in case of a hash conflict
callback();
return;
}
const FS = this.fs || fs;
async.each(cacheData.dependencies.concat(cacheData.contextDependencies), (dep, eachCallback) => {
FS.stat(dep.path, (statErr, stats) => {
if (statErr) {
eachCallback(statErr);
return;
}
if (stats.mtime.getTime() !== dep.mtime) {
eachCallback(true);
return;
}
eachCallback();
});
}, err => {
if (err) {
data.startTime = Date.now();
callback();
return;
}
cacheData.dependencies.forEach(dep => this.addDependency(pathWithCacheContext(cacheContext, dep.path)));
cacheData.contextDependencies.forEach(dep => this.addContextDependency(pathWithCacheContext(cacheContext, dep.path)));
callback(null, ...cacheData.result);
});
});
}
function digest(str) {
return crypto.createHash('md5').update(str).digest('hex');
}
const directories = new Set();
function write(key, data, callback) {
const dirname = path.dirname(key);
const content = JSON.stringify(data);
if (directories.has(dirname)) {
// for performance skip creating directory
fs.writeFile(key, content, 'utf-8', callback);
} else {
mkdirp(dirname, mkdirErr => {
if (mkdirErr) {
callback(mkdirErr);
return;
}
directories.add(dirname);
fs.writeFile(key, content, 'utf-8', callback);
});
}
}
function read(key, callback) {
fs.readFile(key, 'utf-8', (err, content) => {
if (err) {
callback(err);
return;
}
try {
const data = JSON.parse(content);
callback(null, data);
} catch (e) {
callback(e);
}
});
}
function cacheKey(options, request) {
const {
cacheIdentifier,
cacheDirectory
} = options;
const hash = digest(`${cacheIdentifier}\n${request}`);
return path.join(cacheDirectory, `${hash}.json`);
}