Comparing version 0.1.1 to 0.1.2
125
autoload.js
@@ -57,3 +57,3 @@ var fs = require('fs'); | ||
var symbols = []; | ||
for (var match = rx.exec(source); match !== null; match = rx.exec()) { | ||
for (var match = rx.exec(source); match !== null; match = rx.exec(source)) { | ||
symbols.push(match[1]); | ||
@@ -68,3 +68,3 @@ } | ||
++count; | ||
match = rx.exec(); | ||
match = rx.exec(source); | ||
} | ||
@@ -104,5 +104,39 @@ if (count !== symbols.length) { | ||
*/ | ||
function autoload(root, loaders, ondone) { | ||
function autoload(root, loaders, cachePath, ondone) { | ||
if (!ondone) { | ||
ondone = cachePath; | ||
cachePath = undefined; | ||
} | ||
var cache = Object.create(null); | ||
function injectSymbols(path, loader, symbols) { | ||
for (var ii = 0; ii < symbols.length; ++ii) { | ||
// It's possible the symbol has already been defined, in which case we should avoid | ||
// clobbering it with the autoloader. | ||
if (!loader.scope.hasOwnProperty(symbols[ii])) { | ||
~function(loader, symbol) { | ||
Object.defineProperty(loader.scope, symbol, { | ||
get: function() { | ||
delete loader.scope[symbol]; | ||
loader.require(path); | ||
if (loader.scope.hasOwnProperty(symbol)) { | ||
return loader.scope[symbol]; | ||
} else { | ||
throw new Error('Failed to autoload ' + symbol); | ||
} | ||
}, | ||
set: function(val) { | ||
delete loader.scope[symbol]; | ||
loader.scope[symbol] = val; | ||
}, | ||
configurable: true, | ||
enumerable: true, | ||
}); | ||
}(loader, symbols[ii]); | ||
} | ||
} | ||
} | ||
function autoloader(path, ondone) { | ||
var fullPath = joinPath(root, path); | ||
var fullPath = path ? joinPath(root, path) : root; | ||
@@ -126,44 +160,39 @@ fs.stat(fullPath, function(err, stat) { | ||
// Read the file from disk to pass to parsers | ||
fs.readFile(fullPath, 'utf-8', function(err, source) { | ||
if (err) { | ||
throw new Error(err); | ||
} | ||
// Exists in cache? | ||
if (fullPath in cache && cache[fullPath].mtime === +stat.mtime) { | ||
for (var ii = 0; ii < loaders.length; ++ii) { | ||
if (loaders[ii].pattern.test(path)) { | ||
// Parse and register autoloading loaders | ||
var symbols = loaders[ii].parse(source); | ||
for (var jj = 0; jj < symbols.length; ++jj) { | ||
// It's possible the symbol has already been defined, in which case we should avoid | ||
// clobbering it with the autoloader. | ||
if (!loaders[ii].scope.hasOwnProperty(symbols[jj])) { | ||
~function(loader, symbol) { | ||
Object.defineProperty(loader.scope, symbol, { | ||
get: function() { | ||
delete loader.scope[symbol]; | ||
loader.require(path); | ||
if (loader.scope.hasOwnProperty(symbol)) { | ||
return loader.scope[symbol]; | ||
} else { | ||
throw new Error('Failed to autoload ' + symbol); | ||
} | ||
}, | ||
set: function(val) { | ||
delete loader.scope[symbol]; | ||
loader.scope[symbol] = val; | ||
}, | ||
configurable: true, | ||
enumerable: true, | ||
}); | ||
}(loaders[ii], symbols[jj]); | ||
} | ||
} | ||
var symbols = cache[fullPath].symbols[ii]; | ||
injectSymbols(path, loaders[ii], symbols); | ||
} | ||
} | ||
ondone(); | ||
}); | ||
} else { | ||
} else if (stat.isDirectory()) { | ||
// Read the file from disk to pass to parsers | ||
fs.readFile(fullPath, 'utf-8', function(err, source) { | ||
if (err) { | ||
throw new Error(err); | ||
} | ||
cache[fullPath] = { | ||
mtime: +stat.mtime, | ||
symbols: [], | ||
}; | ||
for (var ii = 0; ii < loaders.length; ++ii) { | ||
if (loaders[ii].pattern.test(path)) { | ||
// Parse and register autoloading loaders | ||
var symbols = loaders[ii].parse(source, path); | ||
cache[fullPath].symbols.push(symbols); | ||
injectSymbols(path, loaders[ii], symbols); | ||
} else { | ||
cache[fullPath].symbols.push(null); | ||
} | ||
} | ||
ondone(); | ||
}); | ||
} | ||
} else if (stat.isDirectory() && path !== 'node_modules') { | ||
// Descend directory | ||
@@ -185,3 +214,3 @@ fs.readdir(fullPath, function(err, files) { | ||
~function(a) { | ||
autoloader(joinPath(path, files[ii]), function() { | ||
autoloader(path ? joinPath(path, files[ii]) : files[ii], function() { | ||
if (!--remaining) { | ||
@@ -202,3 +231,17 @@ return ondone(); | ||
} | ||
autoloader(false, ondone); | ||
if (cachePath) { | ||
fs.readFile(cachePath, 'utf-8', function(err, val) { | ||
if (!err) { | ||
try { | ||
cache = JSON.parse(val); | ||
cache.__proto__ = null; | ||
} catch (err) {} | ||
} | ||
autoloader(false, function(err, val) { | ||
fs.writeFile(cachePath, JSON.stringify(cache), 'utf-8', ondone); | ||
}); | ||
}); | ||
} else { | ||
autoloader(false, ondone); | ||
} | ||
} |
{ | ||
"name": "autoload", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"description": "Autoloading symbols via source code grokking", | ||
@@ -5,0 +5,0 @@ "keywords": ["autoload", "require"], |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
10339
225
0
1