'use strict'; var isNative = /\.node$/; function forEach(obj, callback) { for ( var key in obj ) { if (!Object.prototype.hasOwnProperty.call(obj, key)) { continue; } callback(key); } } function assign(target, source) { forEach(source, function (key) { target[key] = source[key]; }); return target; } function clearCache(requireCache) { forEach(requireCache, function (resolvedPath) { if (!isNative.test(resolvedPath)) { delete requireCache[resolvedPath]; } }); } module.exports = function (requireCache, callback, callbackForModulesToKeep, module) { var originalCache = assign({}, requireCache); clearCache(requireCache); if (callbackForModulesToKeep) { var originalModuleChildren = module.children ? module.children.slice() : false; // Creates a shallow copy of module.children callbackForModulesToKeep(); // Lists the cache entries made by callbackForModulesToKeep() var modulesToKeep = []; forEach(requireCache, function (key) { modulesToKeep.push(key); }); // Discards the modules required in callbackForModulesToKeep() clearCache(requireCache); if (module.children) { // Only true for node.js module.children = originalModuleChildren; // Removes last references to modules required in callbackForModulesToKeep() -> No memory leak } // Takes the cache entries of the original cache in case the modules where required before for ( var i = 0; i < modulesToKeep.length; i+=1 ) { if (originalCache[modulesToKeep[i]]) { requireCache[modulesToKeep[i]] = originalCache[modulesToKeep[i]]; } } } var freshModule = callback(); var stealthCache = callbackForModulesToKeep ? assign({}, requireCache) : false; clearCache(requireCache); if (callbackForModulesToKeep) { // In case modules to keep were required inside the stealthy require for the first time, copy them to the restored cache for ( var k = 0; k < modulesToKeep.length; k+=1 ) { if (stealthCache[modulesToKeep[k]]) { requireCache[modulesToKeep[k]] = stealthCache[modulesToKeep[k]]; } } } assign(requireCache, originalCache); return freshModule; };