UNPKG

wipe-node-cache

Version:

Wipes node.js cache in a controlled way.

138 lines (116 loc) 4.36 kB
"use strict"; 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;