mirror of
				https://github.com/Jermolene/TiddlyWiki5
				synced 2025-10-31 15:42:59 +00:00 
			
		
		
		
	Major refactoring of async code
The result is correct handling of tiddlers being overwritten within recipes.
This commit is contained in:
		| @@ -11,19 +11,16 @@ var fs = require("fs"), | ||||
| 	url = require("url"), | ||||
| 	util = require("util"), | ||||
| 	http = require("http"), | ||||
| 	https = require("https"), | ||||
| 	async = require("async"); | ||||
| 	https = require("https"); | ||||
|  | ||||
| var FileRetriever = exports; | ||||
|  | ||||
| var fileRequestQueue = async.queue(function(task,callback) { | ||||
| 	fs.readFile(task.filepath,"utf8", function(err,data) { | ||||
| 		callback(err,data); | ||||
| 	}); | ||||
| },10); | ||||
| var fileRequest = function fileRequest(filepath,callback) { | ||||
| 	fs.readFile(filepath,"utf8", callback); | ||||
| }; | ||||
|  | ||||
| var httpRequestQueue = async.queue(function(task,callback) { | ||||
| 	var opts = url.parse(task.url); | ||||
| var httpRequest = function(fileurl,callback) { | ||||
| 	var opts = url.parse(fileurl); | ||||
| 	var httpLib = opts.protocol === "http:" ? http : https; | ||||
| 	var request = httpLib.get(opts,function(res) { | ||||
| 		if(res.statusCode != 200) { | ||||
| @@ -44,33 +41,40 @@ var httpRequestQueue = async.queue(function(task,callback) { | ||||
| 		callback(err); | ||||
| 	}); | ||||
| 	request.end(); | ||||
| },4); | ||||
| }; | ||||
|  | ||||
| // Retrieve a file given a filepath specifier and a context path. If the filepath isn't an absolute | ||||
| // filepath or an absolute URL, then it is interpreted relative to the context path, which can also be | ||||
| // a filepath or a URL. On completion, the callback function is called as callback(err,data). It | ||||
| // returns an object: | ||||
| // a filepath or a URL. On completion, the callback function is called as callback(err,data). The | ||||
| // data hashmap is as follows: | ||||
| //		text: full text of file | ||||
| //		path: full path used to reach the file | ||||
| //		basename: the basename of the file (used as the default tiddler title) | ||||
| //		basename: the basename of the file | ||||
| //		extname: the extension of the file | ||||
| FileRetriever.retrieveFile = function(filepath,contextPath,callback) { | ||||
| 	var httpRegExp = /^(https?:\/\/)/gi, | ||||
| 		result = {}, | ||||
| 		filepathIsHttp = httpRegExp.test(filepath), | ||||
| 		contextPathIsHttp = httpRegExp.test(contextPath); | ||||
| 		contextPathIsHttp = httpRegExp.test(contextPath), | ||||
| 		requester; | ||||
| 	if(contextPathIsHttp || filepathIsHttp) { | ||||
| 		// If we've got a full HTTP URI then we're good to go | ||||
| 		result.path = url.resolve(contextPath,filepath); | ||||
| 		var parsedPath = url.parse(result.path); | ||||
| 		result.extname = path.extname(parsedPath.pathname); | ||||
| 		result.basename = path.basename(parsedPath.extname); | ||||
| 		httpRequestQueue.push({url: result.path},callback); | ||||
| 		requester = httpRequest; | ||||
| 	} else { | ||||
| 		// It's a file requested in a file context | ||||
| 		result.path = path.resolve(path.dirname(contextPath),filepath); | ||||
| 		result.extname = path.extname(result.path); | ||||
| 		result.basename = path.basename(result.path,result.extname); | ||||
| 		fileRequestQueue.push({filepath: result.path},callback); | ||||
| 		requester = fileRequest; | ||||
| 	} | ||||
| 	return result; | ||||
| 	requester(result.path,function(err,data) { | ||||
| 		if(!err) { | ||||
| 			result.text = data; | ||||
| 		} | ||||
| 		callback(err,result); | ||||
| 	}); | ||||
| }; | ||||
|   | ||||
							
								
								
									
										237
									
								
								js/Recipe.js
									
									
									
									
									
								
							
							
						
						
									
										237
									
								
								js/Recipe.js
									
									
									
									
									
								
							| @@ -2,9 +2,9 @@ | ||||
|  | ||||
| Recipe files consist of recipe lines consisting of a marker, a colon and the pathname of an ingredient: | ||||
|  | ||||
| marker: pathname | ||||
| marker: filepath | ||||
|  | ||||
| The pathname is interpreted relative to the directory containing the recipe file. | ||||
| The filepath is interpreted relative to the directory containing the recipe file. | ||||
|  | ||||
| The special marker "recipe" is used to load a sub-recipe file. | ||||
|  | ||||
| @@ -14,16 +14,35 @@ markers in two different forms: | ||||
| <!--@@marker@@--> | ||||
| <!--@@marker@@--> | ||||
|  | ||||
| Recipe processing is in two parts. First the recipe file is parsed and the referenced files are loaded into tiddlers. | ||||
| Second, the template is processed by replacing the markers with the text of the tiddlers indicated in the recipe file. | ||||
| Recipe processing is in four parts: | ||||
|  | ||||
| The recipe is parsed into the 'ingredients' hashmap like this: | ||||
| 1) The recipe file is parsed and any subrecipe files loaded recursively into this structure: | ||||
|  | ||||
| this.ingredients = { | ||||
| 	"marker1": [Tiddler1,Tiddler2,Tiddler3,...], | ||||
| 	"marker2": [TiddlerA,TiddlerB,TiddlerC,...], | ||||
| 	.... | ||||
| }; | ||||
| 	this.recipe = [ | ||||
| 		{marker: <marker>, filepath: <filepath>, contextPath: <contextPath>}, | ||||
| 		... | ||||
| 		{marker: <marker>, filepath: <filepath>, contextPath: <contextPath>}, | ||||
| 		[ | ||||
| 			{marker: <marker>, filepath: <filepath>, contextPath: <contextPath>}, | ||||
| 			... | ||||
| 			{marker: <marker>, filepath: <filepath>, contextPath: <contextPath>}, | ||||
| 		] | ||||
| 	]; | ||||
|  | ||||
| 2) The tiddler files referenced by the recipe structure are loaded into it as an additional 'tiddlers' | ||||
| member that contains an array of hashmaps of tiddler field values. | ||||
|  | ||||
| 3) The recipe is scanned to create a hashmap of markers and their associated tiddlers. In cases where more | ||||
| than one tiddler with the same title is assigned to a marker, the one that is later in the recipe file wins. | ||||
| At this point tiddlers are placed in the store so that they can be referenced by title | ||||
|  | ||||
| 	this.markers = { | ||||
| 		<marker>: [<tiddler title>,<tiddler title>,...], | ||||
| 		<marker>: [<tiddler title>,<tiddler title>,...], | ||||
| 		... | ||||
| 	} | ||||
|  | ||||
| 4) Finally, the template is processed by replacing the markers with the text of the associated tiddlers | ||||
|  | ||||
| */ | ||||
|  | ||||
| @@ -38,74 +57,102 @@ var Tiddler = require("./Tiddler.js").Tiddler, | ||||
| 	retrieveFile = require("./FileRetriever.js").retrieveFile, | ||||
| 	fs = require("fs"), | ||||
| 	path = require("path"), | ||||
| 	util = require("util"); | ||||
| 	util = require("util"), | ||||
| 	async = require("async"); | ||||
|  | ||||
| // Create a new Recipe object from the specified recipe file, storing the tiddlers in a specified TiddlyWiki store. Invoke | ||||
| // the callback function when all of the referenced tiddlers and recipes have been loaded successfully | ||||
| var Recipe = function(store,filepath,callback) { | ||||
| 	var me = this; | ||||
| 	this.store = store; // Save a reference to the store | ||||
| 	this.ingredients = {}; // Hashmap of array of ingredients | ||||
| 	this.callback = callback; | ||||
| 	this.fetchCount = 0; | ||||
| 	this.readRecipe(filepath,process.cwd()); // Read the recipe file | ||||
| 	this.recipe = []; | ||||
| 	this.markers = {}; | ||||
| 	this.recipeQueue = async.queue(function(task,callback) { | ||||
| 		retrieveFile(task.filepath,task.contextPath,function(err,data) { | ||||
| 			if(err) { | ||||
| 				callback(err); | ||||
| 			} else { | ||||
| 				me.processRecipeFile(task.recipe,data.text,data.path); | ||||
| 				callback(null); | ||||
| 			} | ||||
| 		}); | ||||
| 	},1); | ||||
| 	this.tiddlerQueue = async.queue(function(task,callback) { | ||||
| 		me.readTiddlerFile(task.filepath,task.contextPath,function(err,data) { | ||||
| 			if(err) { | ||||
| 				callback(err); | ||||
| 			} else { | ||||
| 				task.recipeLine.tiddlers = data; | ||||
| 				callback(null); | ||||
| 			} | ||||
| 		}); | ||||
| 	},1); | ||||
| 	this.recipeQueue.drain = function() { | ||||
| 		me.loadTiddlerFiles(me.recipe); | ||||
| 	}; | ||||
| 	this.tiddlerQueue.drain = function() { | ||||
| 		me.chooseTiddlers(me.recipe); | ||||
| 		me.callback(); | ||||
| 	}; | ||||
| 	this.recipeQueue.push({filepath: filepath, | ||||
| 							contextPath: process.cwd(), | ||||
| 							recipe: this.recipe}); | ||||
| }; | ||||
|  | ||||
| // The fetch counter is used to keep track of the number of asynchronous requests outstanding | ||||
| Recipe.prototype.incFetchCount = function() { | ||||
| 	this.fetchCount++; | ||||
| Recipe.prototype.loadTiddlerFiles = function(recipe) { | ||||
| 	for(var r=0; r<recipe.length; r++) { | ||||
| 		var recipeLine = recipe[r]; | ||||
| 		if(recipeLine instanceof Array) { | ||||
| 			this.loadTiddlerFiles(recipeLine);	 | ||||
| 		} else { | ||||
| 			this.tiddlerQueue.push({filepath: recipeLine.filepath, contextPath: recipeLine.contextPath, recipeLine: recipeLine}); | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| // When the fetch counter reaches zero, all the results are in, so invoke the recipe callback | ||||
| Recipe.prototype.decFetchCount = function() { | ||||
| 	if(--this.fetchCount === 0) { | ||||
| 		this.callback(); | ||||
| Recipe.prototype.chooseTiddlers = function(recipe) { | ||||
| 	for(var r=0; r<recipe.length; r++) { | ||||
| 		var recipeLine = recipe[r]; | ||||
| 		if(recipeLine instanceof Array) { | ||||
| 			this.chooseTiddlers(recipeLine); | ||||
| 		} else { | ||||
| 			var markerArray = this.markers[recipeLine.marker]; | ||||
| 			if(markerArray === undefined) { | ||||
| 				this.markers[recipeLine.marker] = []; | ||||
| 				markerArray = this.markers[recipeLine.marker]; | ||||
| 			} | ||||
| 			for(var t=0; t<recipeLine.tiddlers.length; t++) { | ||||
| 				// Only add the tiddler to the marker if it isn't already there | ||||
| 				var found = false; | ||||
| 				for(var m=0; m<markerArray.length; m++) { | ||||
| 					if(markerArray[m] === recipeLine.tiddlers[t].title) { | ||||
| 						found = true; | ||||
| 					} | ||||
| 				} | ||||
| 				if(!found) { | ||||
| 					markerArray.push(recipeLine.tiddlers[t].title); | ||||
| 				} | ||||
| 				this.store.addTiddler(new Tiddler(recipeLine.tiddlers[t])); | ||||
| 			} | ||||
| 		}		 | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| // Process the contents of a recipe file | ||||
| Recipe.prototype.readRecipe = function(filepath,contextPath) { | ||||
| Recipe.prototype.processRecipeFile = function(recipe,text,contextPath) { | ||||
| 	var me = this; | ||||
| 	this.incFetchCount(); | ||||
| 	var rf = retrieveFile(filepath, contextPath, function(err, data) { | ||||
| 		if (err) throw err; | ||||
| 		me.processRecipe(data,rf.path); | ||||
| 		me.decFetchCount(); | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| Recipe.prototype.processRecipe = function (data,contextPath) { | ||||
| 	var me = this; | ||||
| 	data.split("\n").forEach(function(line) { | ||||
| 		var p = line.indexOf(":"); | ||||
| 	text.split("\n").forEach(function(line) { | ||||
| 		var p = line.indexOf(":"), | ||||
| 			insertionPoint; | ||||
| 		if(p !== -1) { | ||||
| 			var marker = line.substr(0, p).trim(), | ||||
| 				value = line.substr(p+1).trim(); | ||||
| 			if(marker === "recipe") { | ||||
| 				me.readRecipe(value,contextPath); | ||||
| 				insertionPoint = recipe.push([]) - 1; | ||||
| 				me.recipeQueue.push({filepath: value, contextPath: contextPath, recipe: recipe[insertionPoint]}); | ||||
| 			} else { | ||||
| 				// Reserve a place in the ingredients array for this ingredient, just to keep tiddler ordering | ||||
| 				// compatible with cook.rb | ||||
| 				if(!(marker in me.ingredients)) { | ||||
| 					me.ingredients[marker] = []; | ||||
| 				} | ||||
| 				var ingredientLocation = me.ingredients[marker].push(null) - 1; | ||||
| 				me.readIngredient(value,contextPath,function(tiddlers) { | ||||
| 					for(var t=0; t<tiddlers.length; t++) { | ||||
| 						var fields = tiddlers[t]; | ||||
| 						var postProcess = me.readIngredientPostProcess[marker]; | ||||
| 						if(postProcess) { | ||||
| 							fields = postProcess(fields); | ||||
| 						} | ||||
| 						var ingredientTiddler = new Tiddler(fields); | ||||
| 						me.store.addTiddler(ingredientTiddler); | ||||
| 						if(ingredientLocation !== -1) { | ||||
| 							me.ingredients[marker][ingredientLocation] = ingredientTiddler; | ||||
| 							ingredientLocation = -1; | ||||
| 						} else { | ||||
| 							me.ingredients[marker].push(ingredientTiddler);		 | ||||
| 						} | ||||
| 					} | ||||
| 				}); | ||||
| 				recipe.push({marker: marker, filepath: value, contextPath: contextPath}); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| @@ -120,43 +167,40 @@ Recipe.prototype.readIngredientPostProcess = { | ||||
| 	}	 | ||||
| }; | ||||
|  | ||||
| // Read an ingredient file and callback with an array of hashmaps of tiddler fields. For single | ||||
| // Read a tiddler file and callback with an array of hashmaps of tiddler fields. For single | ||||
| // tiddler files it also looks for an accompanying .meta file | ||||
| Recipe.prototype.readIngredient = function(filepath,contextPath,callback) { | ||||
| Recipe.prototype.readTiddlerFile = function(filepath,contextPath,callback) { | ||||
| 	var me = this; | ||||
| 	me.incFetchCount(); | ||||
| 	// Read the tiddler file | ||||
| 	var rf = retrieveFile(filepath,contextPath,function(err,data) { | ||||
| 	retrieveFile(filepath,contextPath,function(err,data) { | ||||
| 		if (err) throw err; | ||||
| 		var fields = { | ||||
| 			title: rf.basename | ||||
| 			title: data.path | ||||
| 		}; | ||||
| 		var tiddlers = tiddlerInput.parseTiddlerFile(data,rf.extname,fields); | ||||
| 		var tiddlers = tiddlerInput.parseTiddlerFile(data.text,data.extname,fields); | ||||
| 		// Check for the .meta file | ||||
| 		if(rf.extname !== ".json" && tiddlers.length === 1) { | ||||
| 		if(data.extname !== ".json" && tiddlers.length === 1) { | ||||
| 			var metafile = filepath + ".meta"; | ||||
| 			me.incFetchCount(); | ||||
| 			retrieveFile(metafile,contextPath,function(err,data) { | ||||
| 				if(err && err.code !== "ENOENT" && err.code !== "404") { | ||||
| 					throw err; | ||||
| 				} | ||||
| 					callback(err); | ||||
| 				} else { | ||||
| 					var fields = tiddlers[0]; | ||||
| 					if(!err) { | ||||
| 					fields = tiddlerInput.parseMetaDataBlock(data,fields); | ||||
| 						fields = tiddlerInput.parseMetaDataBlock(data.text,fields); | ||||
| 					} | ||||
| 					callback(null,[fields]); | ||||
| 				} | ||||
| 				callback([fields]); | ||||
| 				me.decFetchCount(); | ||||
| 			}); | ||||
| 		} else { | ||||
| 			callback(tiddlers); | ||||
| 			callback(null,tiddlers); | ||||
| 		} | ||||
| 		me.decFetchCount(); | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| // Return a string of the cooked recipe | ||||
| Recipe.prototype.cook = function() { | ||||
| 	var template = this.ingredients.template ? this.ingredients.template[0].fields.text : "", | ||||
| 	var template = this.markers.template ? this.store.getTiddlerText(this.markers.template[0]) : "", | ||||
| 		out = [], | ||||
| 		me = this; | ||||
| 	template.split("\n").forEach(function(line) { | ||||
| @@ -164,7 +208,7 @@ Recipe.prototype.cook = function() { | ||||
| 		var match = templateRegExp.exec(line); | ||||
| 		if(match) { | ||||
| 			var marker = match[1] === undefined ? match[2] : match[1]; | ||||
| 			me.outputIngredient(out,marker); | ||||
| 			me.outputTiddlersForMarker(out,marker); | ||||
| 		} else { | ||||
| 			out.push(line); | ||||
| 		} | ||||
| @@ -173,17 +217,17 @@ Recipe.prototype.cook = function() { | ||||
| }; | ||||
|  | ||||
| // Output all the tiddlers in the recipe with a particular marker | ||||
| Recipe.prototype.outputIngredient = function(out,marker) { | ||||
| 	var ingredient = this.ingredients[marker], | ||||
| 		outputType = Recipe.ingredientOutputMapper[marker] || "raw", | ||||
| 		outputter = Recipe.ingredientOutputter[outputType]; | ||||
| 	if(outputter && ingredient) { | ||||
| 		outputter(out,ingredient); | ||||
| Recipe.prototype.outputTiddlersForMarker = function(out,marker) { | ||||
| 	var tiddlers = this.markers[marker], | ||||
| 		outputType = Recipe.tiddlerOutputMapper[marker] || "raw", | ||||
| 		outputter = Recipe.tiddlerOutputter[outputType]; | ||||
| 	if(outputter && tiddlers) { | ||||
| 		outputter.call(this,out,tiddlers); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| // Allows for specialised processing for certain markers | ||||
| Recipe.ingredientOutputMapper = { | ||||
| Recipe.tiddlerOutputMapper = { | ||||
| 	tiddler: "div", | ||||
| 	js: "javascript", | ||||
| 	jsdeprecated: "javascript", | ||||
| @@ -191,28 +235,27 @@ Recipe.ingredientOutputMapper = { | ||||
| 	shadow: "shadow" | ||||
| }; | ||||
|  | ||||
| Recipe.ingredientOutputter = { | ||||
| 	raw: function(out,ingredient) { | ||||
| Recipe.tiddlerOutputter = { | ||||
| 	raw: function(out,tiddlers) { | ||||
| 		// The default is just to output the raw text of the tiddler, ignoring any metadata | ||||
| 		for(var t=0; t<ingredient.length; t++) { | ||||
| 			var tid = ingredient[t]; | ||||
| 		for(var t=0; t<tiddlers.length; t++) { | ||||
| 			// For compatibility with cook.rb, remove one trailing \n from tiddler | ||||
| 			var text = tid.fields.text; | ||||
| 			var text = this.store.getTiddlerText(tiddlers[t]); | ||||
| 			text = text.charAt(text.length-1) === "\n" ? text.substr(0,text.length-1) : text; | ||||
| 			out.push(text); | ||||
| 		} | ||||
| 	}, | ||||
| 	div: function(out,ingredient) { | ||||
| 	div: function(out,tiddlers) { | ||||
| 		// Ordinary tiddlers are output as a <DIV> | ||||
| 		for(var t=0; t<ingredient.length; t++) { | ||||
| 			var tid = ingredient[t]; | ||||
| 		for(var t=0; t<tiddlers.length; t++) { | ||||
| 			var tid = this.store.getTiddler(tiddlers[t]); | ||||
| 			out.push(tiddlerOutput.outputTiddlerDiv(tid)); | ||||
| 		} | ||||
| 	}, | ||||
| 	javascript: function(out,ingredient) { | ||||
| 	javascript: function(out,tiddlers) { | ||||
| 		// Lines starting with //# are removed from javascript tiddlers | ||||
| 		for(var t=0; t<ingredient.length; t++) { | ||||
| 			var tid = ingredient[t], | ||||
| 		for(var t=0; t<tiddlers.length; t++) { | ||||
| 			var tid = this.store.getTiddler(tiddlers[t]), | ||||
| 				text = tid.fields.text; | ||||
| 			// For compatibility with cook.rb, remove one trailing \n from tiddler | ||||
| 			text = text.charAt(text.length-1) === "\n" ? text.substr(0,text.length-1) : text; | ||||
| @@ -225,11 +268,11 @@ Recipe.ingredientOutputter = { | ||||
| 			}	 | ||||
| 		} | ||||
| 	}, | ||||
| 	shadow: function(out,ingredient) { | ||||
| 	shadow: function(out,tiddlers) { | ||||
| 		// Shadows are output as a <DIV> with the the ".shadow" suffix removed from the title | ||||
| 		for(var t=0; t<ingredient.length; t++) { | ||||
| 			var tid = ingredient[t], | ||||
| 				title = tid.fields.title, | ||||
| 		for(var t=0; t<tiddlers.length; t++) { | ||||
| 			var title = tiddlers[t], | ||||
| 				tid = this.store.getTiddler(title), | ||||
| 				tweakedTiddler; | ||||
| 			if(title.indexOf(".shadow") === title.length - 7) { | ||||
| 				tweakedTiddler = new Tiddler(tid,{ | ||||
|   | ||||
| @@ -27,7 +27,7 @@ TiddlyWiki.prototype.deleteTiddler = function(title) { | ||||
|  | ||||
| TiddlyWiki.prototype.isTiddler = function(title) { | ||||
| 	return this.tiddlers[title] instanceof Tiddler; | ||||
| } | ||||
| }; | ||||
|  | ||||
| TiddlyWiki.prototype.addTiddler = function(tiddler) { | ||||
| 	this.tiddlers[tiddler.fields.title] = tiddler; | ||||
|   | ||||
							
								
								
									
										9
									
								
								node_modules/async/.gitmodules
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								node_modules/async/.gitmodules
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,9 +0,0 @@ | ||||
| [submodule "deps/nodeunit"] | ||||
| 	path = deps/nodeunit | ||||
| 	url = git://github.com/caolan/nodeunit.git | ||||
| [submodule "deps/UglifyJS"] | ||||
| 	path = deps/UglifyJS | ||||
| 	url = https://github.com/mishoo/UglifyJS.git | ||||
| [submodule "deps/nodelint"] | ||||
| 	path = deps/nodelint | ||||
| 	url = https://github.com/tav/nodelint.git | ||||
							
								
								
									
										19
									
								
								node_modules/async/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								node_modules/async/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,19 +0,0 @@ | ||||
| Copyright (c) 2010 Caolan McMahon | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| THE SOFTWARE. | ||||
							
								
								
									
										21
									
								
								node_modules/async/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								node_modules/async/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,21 +0,0 @@ | ||||
| PACKAGE = asyncjs | ||||
| NODEJS = $(if $(shell test -f /usr/bin/nodejs && echo "true"),nodejs,node) | ||||
|  | ||||
| BUILDDIR = dist | ||||
|  | ||||
| all: build | ||||
|  | ||||
| build: $(wildcard  lib/*.js) | ||||
| 	mkdir -p $(BUILDDIR) | ||||
| 	uglifyjs lib/async.js > $(BUILDDIR)/async.min.js | ||||
|  | ||||
| test: | ||||
| 	nodeunit test | ||||
|  | ||||
| clean: | ||||
| 	rm -rf $(BUILDDIR) | ||||
|  | ||||
| lint: | ||||
| 	nodelint --config nodelint.cfg lib/async.js | ||||
|  | ||||
| .PHONY: test build all | ||||
							
								
								
									
										1009
									
								
								node_modules/async/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1009
									
								
								node_modules/async/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										70
									
								
								node_modules/async/deps/nodeunit.css
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										70
									
								
								node_modules/async/deps/nodeunit.css
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,70 +0,0 @@ | ||||
| /*! | ||||
|  * Styles taken from qunit.css | ||||
|  */ | ||||
|  | ||||
| h1#nodeunit-header, h1.nodeunit-header { | ||||
|     padding: 15px; | ||||
|     font-size: large; | ||||
|     background-color: #06b; | ||||
|     color: white; | ||||
|     font-family: 'trebuchet ms', verdana, arial; | ||||
|     margin: 0; | ||||
| } | ||||
|  | ||||
| h1#nodeunit-header a { | ||||
|     color: white; | ||||
| } | ||||
|  | ||||
| h2#nodeunit-banner { | ||||
|     height: 2em; | ||||
|     border-bottom: 1px solid white; | ||||
|     background-color: #eee; | ||||
|     margin: 0; | ||||
|     font-family: 'trebuchet ms', verdana, arial; | ||||
| } | ||||
| h2#nodeunit-banner.pass { | ||||
|     background-color: green; | ||||
| } | ||||
| h2#nodeunit-banner.fail { | ||||
|     background-color: red; | ||||
| } | ||||
|  | ||||
| h2#nodeunit-userAgent, h2.nodeunit-userAgent { | ||||
|     padding: 10px; | ||||
|     background-color: #eee; | ||||
|     color: black; | ||||
|     margin: 0; | ||||
|     font-size: small; | ||||
|     font-weight: normal; | ||||
|     font-family: 'trebuchet ms', verdana, arial; | ||||
|     font-size: 10pt; | ||||
| } | ||||
|  | ||||
| div#nodeunit-testrunner-toolbar { | ||||
|     background: #eee; | ||||
|     border-top: 1px solid black; | ||||
|     padding: 10px; | ||||
|     font-family: 'trebuchet ms', verdana, arial; | ||||
|     margin: 0; | ||||
|     font-size: 10pt; | ||||
| } | ||||
|  | ||||
| ol#nodeunit-tests { | ||||
|     font-family: 'trebuchet ms', verdana, arial; | ||||
|     font-size: 10pt; | ||||
| } | ||||
| ol#nodeunit-tests li strong { | ||||
|     cursor:pointer; | ||||
| } | ||||
| ol#nodeunit-tests .pass { | ||||
|     color: green; | ||||
| }  | ||||
| ol#nodeunit-tests .fail { | ||||
|     color: red; | ||||
| }  | ||||
|  | ||||
| p#nodeunit-testresult { | ||||
|     margin-left: 1em; | ||||
|     font-size: 10pt; | ||||
|     font-family: 'trebuchet ms', verdana, arial; | ||||
| } | ||||
							
								
								
									
										1966
									
								
								node_modules/async/deps/nodeunit.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1966
									
								
								node_modules/async/deps/nodeunit.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1
									
								
								node_modules/async/dist/async.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								node_modules/async/dist/async.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										3
									
								
								node_modules/async/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								node_modules/async/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,3 +0,0 @@ | ||||
| // This file is just added for convenience so this repository can be | ||||
| // directly checked out into a project's deps folder | ||||
| module.exports = require('./lib/async'); | ||||
							
								
								
									
										690
									
								
								node_modules/async/lib/async.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										690
									
								
								node_modules/async/lib/async.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,690 +0,0 @@ | ||||
| /*global setTimeout: false, console: false */ | ||||
| (function () { | ||||
|  | ||||
|     var async = {}; | ||||
|  | ||||
|     // global on the server, window in the browser | ||||
|     var root = this, | ||||
|         previous_async = root.async; | ||||
|  | ||||
|     if (typeof module !== 'undefined' && module.exports) { | ||||
|         module.exports = async; | ||||
|     } | ||||
|     else { | ||||
|         root.async = async; | ||||
|     } | ||||
|  | ||||
|     async.noConflict = function () { | ||||
|         root.async = previous_async; | ||||
|         return async; | ||||
|     }; | ||||
|  | ||||
|     //// cross-browser compatiblity functions //// | ||||
|  | ||||
|     var _forEach = function (arr, iterator) { | ||||
|         if (arr.forEach) { | ||||
|             return arr.forEach(iterator); | ||||
|         } | ||||
|         for (var i = 0; i < arr.length; i += 1) { | ||||
|             iterator(arr[i], i, arr); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     var _map = function (arr, iterator) { | ||||
|         if (arr.map) { | ||||
|             return arr.map(iterator); | ||||
|         } | ||||
|         var results = []; | ||||
|         _forEach(arr, function (x, i, a) { | ||||
|             results.push(iterator(x, i, a)); | ||||
|         }); | ||||
|         return results; | ||||
|     }; | ||||
|  | ||||
|     var _reduce = function (arr, iterator, memo) { | ||||
|         if (arr.reduce) { | ||||
|             return arr.reduce(iterator, memo); | ||||
|         } | ||||
|         _forEach(arr, function (x, i, a) { | ||||
|             memo = iterator(memo, x, i, a); | ||||
|         }); | ||||
|         return memo; | ||||
|     }; | ||||
|  | ||||
|     var _keys = function (obj) { | ||||
|         if (Object.keys) { | ||||
|             return Object.keys(obj); | ||||
|         } | ||||
|         var keys = []; | ||||
|         for (var k in obj) { | ||||
|             if (obj.hasOwnProperty(k)) { | ||||
|                 keys.push(k); | ||||
|             } | ||||
|         } | ||||
|         return keys; | ||||
|     }; | ||||
|  | ||||
|     var _indexOf = function (arr, item) { | ||||
|         if (arr.indexOf) { | ||||
|             return arr.indexOf(item); | ||||
|         } | ||||
|         for (var i = 0; i < arr.length; i += 1) { | ||||
|             if (arr[i] === item) { | ||||
|                 return i; | ||||
|             } | ||||
|         } | ||||
|         return -1; | ||||
|     }; | ||||
|  | ||||
|     //// exported async module functions //// | ||||
|  | ||||
|     //// nextTick implementation with browser-compatible fallback //// | ||||
|     if (typeof process === 'undefined' || !(process.nextTick)) { | ||||
|         async.nextTick = function (fn) { | ||||
|             setTimeout(fn, 0); | ||||
|         }; | ||||
|     } | ||||
|     else { | ||||
|         async.nextTick = process.nextTick; | ||||
|     } | ||||
|  | ||||
|     async.forEach = function (arr, iterator, callback) { | ||||
|         if (!arr.length) { | ||||
|             return callback(); | ||||
|         } | ||||
|         var completed = 0; | ||||
|         _forEach(arr, function (x) { | ||||
|             iterator(x, function (err) { | ||||
|                 if (err) { | ||||
|                     callback(err); | ||||
|                     callback = function () {}; | ||||
|                 } | ||||
|                 else { | ||||
|                     completed += 1; | ||||
|                     if (completed === arr.length) { | ||||
|                         callback(); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     }; | ||||
|  | ||||
|     async.forEachSeries = function (arr, iterator, callback) { | ||||
|         if (!arr.length) { | ||||
|             return callback(); | ||||
|         } | ||||
|         var completed = 0; | ||||
|         var iterate = function () { | ||||
|             iterator(arr[completed], function (err) { | ||||
|                 if (err) { | ||||
|                     callback(err); | ||||
|                     callback = function () {}; | ||||
|                 } | ||||
|                 else { | ||||
|                     completed += 1; | ||||
|                     if (completed === arr.length) { | ||||
|                         callback(); | ||||
|                     } | ||||
|                     else { | ||||
|                         iterate(); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|         }; | ||||
|         iterate(); | ||||
|     }; | ||||
|      | ||||
|     async.forEachLimit = function (arr, limit, iterator, callback) { | ||||
|         if (!arr.length || limit <= 0) { | ||||
|             return callback();  | ||||
|         } | ||||
|         var completed = 0; | ||||
|         var started = 0; | ||||
|         var running = 0; | ||||
|          | ||||
|         (function replenish () { | ||||
|           if (completed === arr.length) { | ||||
|               return callback(); | ||||
|           } | ||||
|            | ||||
|           while (running < limit && started < arr.length) { | ||||
|             iterator(arr[started], function (err) { | ||||
|               if (err) { | ||||
|                   callback(err); | ||||
|                   callback = function () {}; | ||||
|               } | ||||
|               else { | ||||
|                   completed += 1; | ||||
|                   running -= 1; | ||||
|                   if (completed === arr.length) { | ||||
|                       callback(); | ||||
|                   } | ||||
|                   else { | ||||
|                       replenish(); | ||||
|                   } | ||||
|               } | ||||
|             }); | ||||
|             started += 1; | ||||
|             running += 1; | ||||
|           } | ||||
|         })(); | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     var doParallel = function (fn) { | ||||
|         return function () { | ||||
|             var args = Array.prototype.slice.call(arguments); | ||||
|             return fn.apply(null, [async.forEach].concat(args)); | ||||
|         }; | ||||
|     }; | ||||
|     var doSeries = function (fn) { | ||||
|         return function () { | ||||
|             var args = Array.prototype.slice.call(arguments); | ||||
|             return fn.apply(null, [async.forEachSeries].concat(args)); | ||||
|         }; | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     var _asyncMap = function (eachfn, arr, iterator, callback) { | ||||
|         var results = []; | ||||
|         arr = _map(arr, function (x, i) { | ||||
|             return {index: i, value: x}; | ||||
|         }); | ||||
|         eachfn(arr, function (x, callback) { | ||||
|             iterator(x.value, function (err, v) { | ||||
|                 results[x.index] = v; | ||||
|                 callback(err); | ||||
|             }); | ||||
|         }, function (err) { | ||||
|             callback(err, results); | ||||
|         }); | ||||
|     }; | ||||
|     async.map = doParallel(_asyncMap); | ||||
|     async.mapSeries = doSeries(_asyncMap); | ||||
|  | ||||
|  | ||||
|     // reduce only has a series version, as doing reduce in parallel won't | ||||
|     // work in many situations. | ||||
|     async.reduce = function (arr, memo, iterator, callback) { | ||||
|         async.forEachSeries(arr, function (x, callback) { | ||||
|             iterator(memo, x, function (err, v) { | ||||
|                 memo = v; | ||||
|                 callback(err); | ||||
|             }); | ||||
|         }, function (err) { | ||||
|             callback(err, memo); | ||||
|         }); | ||||
|     }; | ||||
|     // inject alias | ||||
|     async.inject = async.reduce; | ||||
|     // foldl alias | ||||
|     async.foldl = async.reduce; | ||||
|  | ||||
|     async.reduceRight = function (arr, memo, iterator, callback) { | ||||
|         var reversed = _map(arr, function (x) { | ||||
|             return x; | ||||
|         }).reverse(); | ||||
|         async.reduce(reversed, memo, iterator, callback); | ||||
|     }; | ||||
|     // foldr alias | ||||
|     async.foldr = async.reduceRight; | ||||
|  | ||||
|     var _filter = function (eachfn, arr, iterator, callback) { | ||||
|         var results = []; | ||||
|         arr = _map(arr, function (x, i) { | ||||
|             return {index: i, value: x}; | ||||
|         }); | ||||
|         eachfn(arr, function (x, callback) { | ||||
|             iterator(x.value, function (v) { | ||||
|                 if (v) { | ||||
|                     results.push(x); | ||||
|                 } | ||||
|                 callback(); | ||||
|             }); | ||||
|         }, function (err) { | ||||
|             callback(_map(results.sort(function (a, b) { | ||||
|                 return a.index - b.index; | ||||
|             }), function (x) { | ||||
|                 return x.value; | ||||
|             })); | ||||
|         }); | ||||
|     }; | ||||
|     async.filter = doParallel(_filter); | ||||
|     async.filterSeries = doSeries(_filter); | ||||
|     // select alias | ||||
|     async.select = async.filter; | ||||
|     async.selectSeries = async.filterSeries; | ||||
|  | ||||
|     var _reject = function (eachfn, arr, iterator, callback) { | ||||
|         var results = []; | ||||
|         arr = _map(arr, function (x, i) { | ||||
|             return {index: i, value: x}; | ||||
|         }); | ||||
|         eachfn(arr, function (x, callback) { | ||||
|             iterator(x.value, function (v) { | ||||
|                 if (!v) { | ||||
|                     results.push(x); | ||||
|                 } | ||||
|                 callback(); | ||||
|             }); | ||||
|         }, function (err) { | ||||
|             callback(_map(results.sort(function (a, b) { | ||||
|                 return a.index - b.index; | ||||
|             }), function (x) { | ||||
|                 return x.value; | ||||
|             })); | ||||
|         }); | ||||
|     }; | ||||
|     async.reject = doParallel(_reject); | ||||
|     async.rejectSeries = doSeries(_reject); | ||||
|  | ||||
|     var _detect = function (eachfn, arr, iterator, main_callback) { | ||||
|         eachfn(arr, function (x, callback) { | ||||
|             iterator(x, function (result) { | ||||
|                 if (result) { | ||||
|                     main_callback(x); | ||||
|                     main_callback = function () {}; | ||||
|                 } | ||||
|                 else { | ||||
|                     callback(); | ||||
|                 } | ||||
|             }); | ||||
|         }, function (err) { | ||||
|             main_callback(); | ||||
|         }); | ||||
|     }; | ||||
|     async.detect = doParallel(_detect); | ||||
|     async.detectSeries = doSeries(_detect); | ||||
|  | ||||
|     async.some = function (arr, iterator, main_callback) { | ||||
|         async.forEach(arr, function (x, callback) { | ||||
|             iterator(x, function (v) { | ||||
|                 if (v) { | ||||
|                     main_callback(true); | ||||
|                     main_callback = function () {}; | ||||
|                 } | ||||
|                 callback(); | ||||
|             }); | ||||
|         }, function (err) { | ||||
|             main_callback(false); | ||||
|         }); | ||||
|     }; | ||||
|     // any alias | ||||
|     async.any = async.some; | ||||
|  | ||||
|     async.every = function (arr, iterator, main_callback) { | ||||
|         async.forEach(arr, function (x, callback) { | ||||
|             iterator(x, function (v) { | ||||
|                 if (!v) { | ||||
|                     main_callback(false); | ||||
|                     main_callback = function () {}; | ||||
|                 } | ||||
|                 callback(); | ||||
|             }); | ||||
|         }, function (err) { | ||||
|             main_callback(true); | ||||
|         }); | ||||
|     }; | ||||
|     // all alias | ||||
|     async.all = async.every; | ||||
|  | ||||
|     async.sortBy = function (arr, iterator, callback) { | ||||
|         async.map(arr, function (x, callback) { | ||||
|             iterator(x, function (err, criteria) { | ||||
|                 if (err) { | ||||
|                     callback(err); | ||||
|                 } | ||||
|                 else { | ||||
|                     callback(null, {value: x, criteria: criteria}); | ||||
|                 } | ||||
|             }); | ||||
|         }, function (err, results) { | ||||
|             if (err) { | ||||
|                 return callback(err); | ||||
|             } | ||||
|             else { | ||||
|                 var fn = function (left, right) { | ||||
|                     var a = left.criteria, b = right.criteria; | ||||
|                     return a < b ? -1 : a > b ? 1 : 0; | ||||
|                 }; | ||||
|                 callback(null, _map(results.sort(fn), function (x) { | ||||
|                     return x.value; | ||||
|                 })); | ||||
|             } | ||||
|         }); | ||||
|     }; | ||||
|  | ||||
|     async.auto = function (tasks, callback) { | ||||
|         callback = callback || function () {}; | ||||
|         var keys = _keys(tasks); | ||||
|         if (!keys.length) { | ||||
|             return callback(null); | ||||
|         } | ||||
|  | ||||
|         var results = {}; | ||||
|  | ||||
|         var listeners = []; | ||||
|         var addListener = function (fn) { | ||||
|             listeners.unshift(fn); | ||||
|         }; | ||||
|         var removeListener = function (fn) { | ||||
|             for (var i = 0; i < listeners.length; i += 1) { | ||||
|                 if (listeners[i] === fn) { | ||||
|                     listeners.splice(i, 1); | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         var taskComplete = function () { | ||||
|             _forEach(listeners, function (fn) { | ||||
|                 fn(); | ||||
|             }); | ||||
|         }; | ||||
|  | ||||
|         addListener(function () { | ||||
|             if (_keys(results).length === keys.length) { | ||||
|                 callback(null, results); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         _forEach(keys, function (k) { | ||||
|             var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; | ||||
|             var taskCallback = function (err) { | ||||
|                 if (err) { | ||||
|                     callback(err); | ||||
|                     // stop subsequent errors hitting callback multiple times | ||||
|                     callback = function () {}; | ||||
|                 } | ||||
|                 else { | ||||
|                     var args = Array.prototype.slice.call(arguments, 1); | ||||
|                     if (args.length <= 1) { | ||||
|                         args = args[0]; | ||||
|                     } | ||||
|                     results[k] = args; | ||||
|                     taskComplete(); | ||||
|                 } | ||||
|             }; | ||||
|             var requires = task.slice(0, Math.abs(task.length - 1)) || []; | ||||
|             var ready = function () { | ||||
|                 return _reduce(requires, function (a, x) { | ||||
|                     return (a && results.hasOwnProperty(x)); | ||||
|                 }, true); | ||||
|             }; | ||||
|             if (ready()) { | ||||
|                 task[task.length - 1](taskCallback, results); | ||||
|             } | ||||
|             else { | ||||
|                 var listener = function () { | ||||
|                     if (ready()) { | ||||
|                         removeListener(listener); | ||||
|                         task[task.length - 1](taskCallback, results); | ||||
|                     } | ||||
|                 }; | ||||
|                 addListener(listener); | ||||
|             } | ||||
|         }); | ||||
|     }; | ||||
|  | ||||
|     async.waterfall = function (tasks, callback) { | ||||
|         if (!tasks.length) { | ||||
|             return callback(); | ||||
|         } | ||||
|         callback = callback || function () {}; | ||||
|         var wrapIterator = function (iterator) { | ||||
|             return function (err) { | ||||
|                 if (err) { | ||||
|                     callback(err); | ||||
|                     callback = function () {}; | ||||
|                 } | ||||
|                 else { | ||||
|                     var args = Array.prototype.slice.call(arguments, 1); | ||||
|                     var next = iterator.next(); | ||||
|                     if (next) { | ||||
|                         args.push(wrapIterator(next)); | ||||
|                     } | ||||
|                     else { | ||||
|                         args.push(callback); | ||||
|                     } | ||||
|                     async.nextTick(function () { | ||||
|                         iterator.apply(null, args); | ||||
|                     }); | ||||
|                 } | ||||
|             }; | ||||
|         }; | ||||
|         wrapIterator(async.iterator(tasks))(); | ||||
|     }; | ||||
|  | ||||
|     async.parallel = function (tasks, callback) { | ||||
|         callback = callback || function () {}; | ||||
|         if (tasks.constructor === Array) { | ||||
|             async.map(tasks, function (fn, callback) { | ||||
|                 if (fn) { | ||||
|                     fn(function (err) { | ||||
|                         var args = Array.prototype.slice.call(arguments, 1); | ||||
|                         if (args.length <= 1) { | ||||
|                             args = args[0]; | ||||
|                         } | ||||
|                         callback.call(null, err, args); | ||||
|                     }); | ||||
|                 } | ||||
|             }, callback); | ||||
|         } | ||||
|         else { | ||||
|             var results = {}; | ||||
|             async.forEach(_keys(tasks), function (k, callback) { | ||||
|                 tasks[k](function (err) { | ||||
|                     var args = Array.prototype.slice.call(arguments, 1); | ||||
|                     if (args.length <= 1) { | ||||
|                         args = args[0]; | ||||
|                     } | ||||
|                     results[k] = args; | ||||
|                     callback(err); | ||||
|                 }); | ||||
|             }, function (err) { | ||||
|                 callback(err, results); | ||||
|             }); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     async.series = function (tasks, callback) { | ||||
|         callback = callback || function () {}; | ||||
|         if (tasks.constructor === Array) { | ||||
|             async.mapSeries(tasks, function (fn, callback) { | ||||
|                 if (fn) { | ||||
|                     fn(function (err) { | ||||
|                         var args = Array.prototype.slice.call(arguments, 1); | ||||
|                         if (args.length <= 1) { | ||||
|                             args = args[0]; | ||||
|                         } | ||||
|                         callback.call(null, err, args); | ||||
|                     }); | ||||
|                 } | ||||
|             }, callback); | ||||
|         } | ||||
|         else { | ||||
|             var results = {}; | ||||
|             async.forEachSeries(_keys(tasks), function (k, callback) { | ||||
|                 tasks[k](function (err) { | ||||
|                     var args = Array.prototype.slice.call(arguments, 1); | ||||
|                     if (args.length <= 1) { | ||||
|                         args = args[0]; | ||||
|                     } | ||||
|                     results[k] = args; | ||||
|                     callback(err); | ||||
|                 }); | ||||
|             }, function (err) { | ||||
|                 callback(err, results); | ||||
|             }); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     async.iterator = function (tasks) { | ||||
|         var makeCallback = function (index) { | ||||
|             var fn = function () { | ||||
|                 if (tasks.length) { | ||||
|                     tasks[index].apply(null, arguments); | ||||
|                 } | ||||
|                 return fn.next(); | ||||
|             }; | ||||
|             fn.next = function () { | ||||
|                 return (index < tasks.length - 1) ? makeCallback(index + 1): null; | ||||
|             }; | ||||
|             return fn; | ||||
|         }; | ||||
|         return makeCallback(0); | ||||
|     }; | ||||
|  | ||||
|     async.apply = function (fn) { | ||||
|         var args = Array.prototype.slice.call(arguments, 1); | ||||
|         return function () { | ||||
|             return fn.apply( | ||||
|                 null, args.concat(Array.prototype.slice.call(arguments)) | ||||
|             ); | ||||
|         }; | ||||
|     }; | ||||
|  | ||||
|     var _concat = function (eachfn, arr, fn, callback) { | ||||
|         var r = []; | ||||
|         eachfn(arr, function (x, cb) { | ||||
|             fn(x, function (err, y) { | ||||
|                 r = r.concat(y || []); | ||||
|                 cb(err); | ||||
|             }); | ||||
|         }, function (err) { | ||||
|             callback(err, r); | ||||
|         }); | ||||
|     }; | ||||
|     async.concat = doParallel(_concat); | ||||
|     async.concatSeries = doSeries(_concat); | ||||
|  | ||||
|     async.whilst = function (test, iterator, callback) { | ||||
|         if (test()) { | ||||
|             iterator(function (err) { | ||||
|                 if (err) { | ||||
|                     return callback(err); | ||||
|                 } | ||||
|                 async.whilst(test, iterator, callback); | ||||
|             }); | ||||
|         } | ||||
|         else { | ||||
|             callback(); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     async.until = function (test, iterator, callback) { | ||||
|         if (!test()) { | ||||
|             iterator(function (err) { | ||||
|                 if (err) { | ||||
|                     return callback(err); | ||||
|                 } | ||||
|                 async.until(test, iterator, callback); | ||||
|             }); | ||||
|         } | ||||
|         else { | ||||
|             callback(); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     async.queue = function (worker, concurrency) { | ||||
|         var workers = 0; | ||||
|         var q = { | ||||
|             tasks: [], | ||||
|             concurrency: concurrency, | ||||
|             saturated: null, | ||||
|             empty: null, | ||||
|             drain: null, | ||||
|             push: function (data, callback) { | ||||
|                 q.tasks.push({data: data, callback: callback}); | ||||
|                 if(q.saturated && q.tasks.length == concurrency) q.saturated(); | ||||
|                 async.nextTick(q.process); | ||||
|             }, | ||||
|             process: function () { | ||||
|                 if (workers < q.concurrency && q.tasks.length) { | ||||
|                     var task = q.tasks.shift(); | ||||
|                     if(q.empty && q.tasks.length == 0) q.empty(); | ||||
|                     workers += 1; | ||||
|                     worker(task.data, function () { | ||||
|                         workers -= 1; | ||||
|                         if (task.callback) { | ||||
|                             task.callback.apply(task, arguments); | ||||
|                         } | ||||
|                         if(q.drain && q.tasks.length + workers == 0) q.drain(); | ||||
|                         q.process(); | ||||
|                     }); | ||||
|                 } | ||||
|             }, | ||||
|             length: function () { | ||||
|                 return q.tasks.length; | ||||
|             }, | ||||
|             running: function () { | ||||
|                 return workers; | ||||
|             } | ||||
|         }; | ||||
|         return q; | ||||
|     }; | ||||
|  | ||||
|     var _console_fn = function (name) { | ||||
|         return function (fn) { | ||||
|             var args = Array.prototype.slice.call(arguments, 1); | ||||
|             fn.apply(null, args.concat([function (err) { | ||||
|                 var args = Array.prototype.slice.call(arguments, 1); | ||||
|                 if (typeof console !== 'undefined') { | ||||
|                     if (err) { | ||||
|                         if (console.error) { | ||||
|                             console.error(err); | ||||
|                         } | ||||
|                     } | ||||
|                     else if (console[name]) { | ||||
|                         _forEach(args, function (x) { | ||||
|                             console[name](x); | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|             }])); | ||||
|         }; | ||||
|     }; | ||||
|     async.log = _console_fn('log'); | ||||
|     async.dir = _console_fn('dir'); | ||||
|     /*async.info = _console_fn('info'); | ||||
|     async.warn = _console_fn('warn'); | ||||
|     async.error = _console_fn('error');*/ | ||||
|  | ||||
|     async.memoize = function (fn, hasher) { | ||||
|         var memo = {}; | ||||
|         var queues = {}; | ||||
|         hasher = hasher || function (x) { | ||||
|             return x; | ||||
|         }; | ||||
|         var memoized = function () { | ||||
|             var args = Array.prototype.slice.call(arguments); | ||||
|             var callback = args.pop(); | ||||
|             var key = hasher.apply(null, args); | ||||
|             if (key in memo) { | ||||
|                 callback.apply(null, memo[key]); | ||||
|             } | ||||
|             else if (key in queues) { | ||||
|                 queues[key].push(callback); | ||||
|             } | ||||
|             else { | ||||
|                 queues[key] = [callback]; | ||||
|                 fn.apply(null, args.concat([function () { | ||||
|                     memo[key] = arguments; | ||||
|                     var q = queues[key]; | ||||
|                     delete queues[key]; | ||||
|                     for (var i = 0, l = q.length; i < l; i++) { | ||||
|                       q[i].apply(null, arguments); | ||||
|                     } | ||||
|                 }])); | ||||
|             } | ||||
|         }; | ||||
|         memoized.unmemoized = fn; | ||||
|         return memoized; | ||||
|     }; | ||||
|  | ||||
|     async.unmemoize = function (fn) { | ||||
|       return function () { | ||||
|         return (fn.unmemoized || fn).apply(null, arguments); | ||||
|       } | ||||
|     }; | ||||
|  | ||||
| }()); | ||||
							
								
								
									
										4
									
								
								node_modules/async/nodelint.cfg
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								node_modules/async/nodelint.cfg
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +0,0 @@ | ||||
| var options = { | ||||
|     indent: 4, | ||||
|     onevar: false | ||||
| }; | ||||
							
								
								
									
										16
									
								
								node_modules/async/package.json
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								node_modules/async/package.json
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,16 +0,0 @@ | ||||
| { "name": "async" | ||||
| , "description": "Higher-order functions and common patterns for asynchronous code" | ||||
| , "main": "./index" | ||||
| , "author": "Caolan McMahon" | ||||
| , "version": "0.1.15" | ||||
| , "repository" : | ||||
|   { "type" : "git" | ||||
|   , "url" : "http://github.com/caolan/async.git" | ||||
|   } | ||||
| , "bugs" : { "url" : "http://github.com/caolan/async/issues" } | ||||
| , "licenses" : | ||||
|   [ { "type" : "MIT" | ||||
|     , "url" : "http://github.com/caolan/async/raw/master/LICENSE" | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										1577
									
								
								node_modules/async/test/test-async.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1577
									
								
								node_modules/async/test/test-async.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										24
									
								
								node_modules/async/test/test.html
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								node_modules/async/test/test.html
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,24 +0,0 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <title>Async.js Test Suite</title> | ||||
|     <!-- | ||||
|       async must be included after nodeunit because nodeunit already uses | ||||
|       the async lib internally and will overwrite the version we want to test | ||||
|     --> | ||||
|     <script src="../deps/nodeunit.js"></script> | ||||
|     <script src="../lib/async.js"></script> | ||||
|     <link rel="stylesheet" href="../deps/nodeunit.css" type="text/css" media="screen" /> | ||||
|     <script> | ||||
|       var _async = this.async; | ||||
|       this.require = function () { return _async; }; | ||||
|       this.exports = {}; | ||||
|     </script> | ||||
|     <script src="test-async.js"></script> | ||||
|   </head> | ||||
|   <body> | ||||
|     <h1 id="nodeunit-header">Async.js Test Suite</h1> | ||||
|     <script> | ||||
|       nodeunit.run({'test-async': exports}); | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
		Reference in New Issue
	
	Block a user
	 Jeremy Ruston
					Jeremy Ruston