wipe-node-cache
Version:
Wipes node.js cache in a controlled way.
138 lines (116 loc) • 4.36 kB
JavaScript
;
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function waveCallback_default() {
return true;
}
function removeFromCache_nodejs(moduleName) {
delete require.cache[moduleName];
}
function assignParents(modules) {
var result = {};
Object.keys(modules).forEach(function (moduleName) {
var parent = modules[moduleName];
var line = parent.children || [];
line.forEach(function (_ref) {
var childName = _ref.id;
result[childName] = result[childName] || { parents: [] };
result[childName].parents.push(moduleName);
});
});
return result;
}
function removeModuleFromParent(parent, removedChild) {
if (parent && parent.children && removedChild) {
parent.children = parent.children.filter(function (child) {
return child !== removedChild;
});
}
}
function burn(cache, wipeList, lookup, callback) {
var removeFromCache = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : removeFromCache_nodejs;
var parentReference = {};
var remove = function remove(moduleName) {
var lookupcache = lookup[moduleName];
var module = cache[moduleName];
delete parentReference[moduleName];
if (lookupcache) {
lookupcache.parents.forEach(function (parent) {
if (!parentReference[parent]) {
parentReference[parent] = [];
}
// set a flag to remove this module from a parent record
parentReference[parent].push(module);
wipeList.push(parent);
});
delete lookup[moduleName];
}
removeFromCache(moduleName);
};
// primary wave
// execute what was set to be removed
var removeList = wipeList;
wipeList = [];
removeList.forEach(remove);
// Secondary wave
// remove parents of evicted modules while possible
while (wipeList.length) {
removeList = wipeList;
wipeList = [];
removeList.forEach(function (moduleName) {
if (callback(moduleName)) {
remove(moduleName);
}
});
}
// post cleanup - remove references from parent
Object.keys(parentReference).forEach(function (parent) {
return parentReference[parent].forEach(function (child) {
return removeModuleFromParent(cache[parent], child);
});
});
}
function purge(cache, wipeList, callback, removeFromCache, parents) {
burn(cache, wipeList, parents || assignParents(cache), callback, removeFromCache);
}
function buildIndexForward(cache) {
return Object.keys(cache);
}
function getCache() {
return require.cache;
}
/**
* Wipes node.js module cache.
* First it look for modules to wipe, and wipe them.
* Second it looks for users of that modules and wipe them to. Repeat.
* Use waveCallback to control secondary wave.
* @param {Object} stubs Any objects, which will just be passed as first parameter to resolver.
* @param {Function} resolver function(stubs, moduleName) which shall return true, if module must be wiped out.
* @param {Function} [waveCallback] function(moduleName) which shall return false, if parent module must not be wiped.
*/
function wipeCache(stubs, resolver, waveCallback) {
var removeFromCache = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : removeFromCache_nodejs;
waveCallback = waveCallback || waveCallback_default;
var cache = require.cache;
wipeMap(cache, function (cache, callback) {
return cache.forEach(function (moduleName) {
return resolver(stubs, moduleName) && callback(moduleName);
});
}, waveCallback, removeFromCache);
}
function wipeMap(cache, callback, waveCallback, removeFromCache) {
var wipeList = [];
var parents = assignParents(cache);
var simpleIndex = buildIndexForward(cache);
var compositeIndex = [].concat(_toConsumableArray(new Set([].concat(_toConsumableArray(simpleIndex), _toConsumableArray(Object.keys(parents))))));
callback(compositeIndex, function (name) {
wipeList.push(name);
});
return purge(cache, wipeList, waveCallback, undefined, parents);
}
exports.buildIndexForward = buildIndexForward;
exports.getCache = getCache;
exports.removeFromCache = removeFromCache_nodejs;
exports.purge = purge;
exports.burn = burn;
exports.wipeCache = wipeCache;
exports.wipeMap = wipeMap;