UNPKG

raptor

Version:

RaptorJS provides an AMD module loader that works in Node, Rhino and the web browser. It also includes various sub-modules to support building optimized web applications.

173 lines (147 loc) 5.89 kB
define('raptor/packaging/DependencyWalker', function(require, module, exports) { var extend = require('raptor').extend, packaging = require('raptor/packaging'), PackageManifest = require('raptor/packaging/PackageManifest'), ExtensionCollection = require('raptor/packaging/ExtensionCollection'); function DependencyWalker() { this.options = { enabledExtensions: require('raptor/packaging').getEnabledExtensions() }; this._visited = {}; this._userDependencyHandler = undefined; this._userManifestHandler = undefined; this._completeHandler = undefined; this._errorHandler = undefined; this._ready = false; this._manifestQueue = []; this._dependencyHandler = function(type, dependency, extension) { if (this._userDependencyHandler) { this._userDependencyHandler(dependency, extension); } }; } DependencyWalker.prototype = { _notifyError: function(err) { if (this.errorHandler) { this.errorHandler(err); } else { throw err; } }, onComplete: function(completeHandler) { this._completeHandler = completeHandler; return this; }, onError: function(errorHandler) { this._errorHandler = errorHandler; return this; }, onDependency: function(dependencyHandler) { this._userDependencyHandler = dependencyHandler; return this; }, onManifest: function(manifestHandler) { this._userManifestHandler = manifestHandler; return this; }, enableExtensions: function(enabledExtensions) { if (enabledExtensions instanceof ExtensionCollection) { this.options.enabledExtensions = enabledExtensions; } else { this.options.enabledExtensions = new ExtensionCollection(enabledExtensions); } return this; }, walkManifest: function(packageManifest) { if (!this._ready) { this._manifestQueue.push(packageManifest); return; } var dependency, key; if (!PackageManifest.isPackageManifest(packageManifest)) { dependency = packageManifest; var resource = this.getResource(dependency); if (resource) { key = PackageManifest.getResourceKey(resource); if (this._visited[key] !== undefined) { // don't actually load the manifest if we know we've seen it before return this; } } packageManifest = this.getManifest(dependency); } else { key = packageManifest.getKey(); if (this._visited[key] !== undefined) { // we've visited this manifest before so skip it by returning early return this; } } this._visited[key] = true; if (this._userManifestHandler) { this._userManifestHandler(packageManifest, dependency); } packageManifest.forEachDependency(this._dependencyHandler, this, this.options); return this; }, walkPackage: function(packageName) { try { this.walkManifest(packaging.getPackageManifest(packageName)); } catch(err) { this._notifyError(err); } return this; }, walkModule: function(moduleName) { try { this.walkManifest(packaging.getModuleManifest(moduleName)); } catch(err) { this._notifyError(err); } return this; }, isPackage: function(dependencyConfig) { return (dependencyConfig.type === 'package'); }, isModule: function(dependencyConfig) { return (dependencyConfig.type === 'module'); }, hasManifest: function(dependency) { return (dependency.isPackageDependency && dependency.isPackageDependency()) || this.isModule(dependency) || this.isPackage(dependency); }, getResource: function(dependency) { var path; if (dependency.getResourcePath && (path = dependency.getResourcePath())) { return packaging.getPackageManifestResource(path); } else if (dependency.path) { return packaging.getPackageManifestResource(dependency.path); } else if (dependency.name) { return packaging.getPackageManifestResourceForModule(dependency.name); } else { return null; } }, getManifest: function(dependency) { if (dependency.getManifest) { return dependency.getManifest(); } else if (this.isModule(dependency)) { packaging.getModuleManifest(dependency.name); } else if (this.isPackage(dependency)) { packaging.getPackageManifest(dependency.path); } else { this._notifyError(new Error('Dependency "' + dependency + '" does not have a package manifest.')); } }, start: function() { this._ready = true; var queue = this._manifestQueue; for (var i = 0, len = queue.length; i < len; i++) { this.walkManifest(queue[i]); } if (this._completeHandler) { this._completeHandler(); } } }; return DependencyWalker; });