Created
October 28, 2009 21:12
-
-
Save kriskowal/220846 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/README.md b/README.md | |
index 080765b..39dfd00 100644 | |
--- a/README.md | |
+++ b/README.md | |
@@ -59,6 +59,7 @@ Contributors | |
* [Isaac Z. Schlueter](http://blog.izs.me/) | |
* [Kris Zyp](http://www.sitepen.com/blog/author/kzyp/) | |
* [Nathan Stott](http://nathan.whiteboard-it.com/) | |
+* [Toby Ho](http://tobyho.com) | |
License | |
diff --git a/catalog.json b/catalog.json | |
index a227325..67336b7 100644 | |
--- a/catalog.json | |
+++ b/catalog.json | |
@@ -100,6 +100,18 @@ | |
"narwhal-xulrunner": { | |
"name": "narwhal-xulrunner", | |
"engine": "xulrunner", | |
+ "dependencies": [ | |
+ "narwhal" | |
+ ], | |
+ "author": "Irakli Gozalishvili (http://rfobic.wordpress.com/)", | |
+ "description": "XULRunner engine support for Narwhal", | |
+ "keywords": [ | |
+ "narwhal", | |
+ "engine", | |
+ "xulrunner", | |
+ "mozilla", | |
+ "extension" | |
+ ], | |
"githubName": "narwhal-xulrunner", | |
"type": "zip", | |
"location": "http://github.com/Gozala/narwhal-xulrunner/zipball/master" | |
@@ -675,6 +687,7 @@ | |
"author": "Nathan Stott", | |
"email": "nathan.stott@whiteboard-it.com", | |
"dependencies": [ | |
+ "jack", | |
"ejs" | |
], | |
"lib": "lib", | |
@@ -682,6 +695,26 @@ | |
"type": "zip", | |
"location": "http://github.com/nrstott/bogart/zipball/master" | |
}, | |
+ "json-template": { | |
+ "name": "json-template", | |
+ "description": "Minimal but powerful templating language implemented in multiple languages.", | |
+ "keywords": [ | |
+ "template", | |
+ "json" | |
+ ], | |
+ "author": "andychup (http://code.google.com/u/andychup/)", | |
+ "contributors": [ | |
+ "Irakli Gozalishvili (http://rfobic.wordpress.com/)" | |
+ ], | |
+ "lib": "lib", | |
+ "license": [ | |
+ "Apache License 2.0" | |
+ ], | |
+ "dependencies": [], | |
+ "githubName": "json-template", | |
+ "type": "zip", | |
+ "location": "http://github.com/Gozala/json-template/zipball/master" | |
+ }, | |
"ejs": { | |
"name": "ejs", | |
"description": "Embedded JavaScript templating framework", | |
@@ -709,11 +742,34 @@ | |
], | |
"author": "Nathan Stott", | |
"email": "nathan.stott@whiteboard-it.com", | |
- "dependencies": [], | |
+ "dependencies": [ | |
+ "browserjs" | |
+ ], | |
"lib": "lib", | |
"githubName": "narwhal-couchdb", | |
"type": "zip", | |
"location": "http://github.com/nrstott/narwhal-couchdb/zipball/master" | |
+ }, | |
+ "mongodb": { | |
+ "name": "mongodb", | |
+ "description": "API to access MongoDB, a schema-free database of JSON documents", | |
+ "keywords": [ | |
+ "mongo", | |
+ "database", | |
+ "document", | |
+ "mongodb", | |
+ "db" | |
+ ], | |
+ "author": "Sergi Mansilla (http://www.sergimansilla.com) <sergi.mansilla@gmail.com>", | |
+ "jars": [ | |
+ "jars/mongo-0.11.jar" | |
+ ], | |
+ "email": "sergi.mansilla@gmail.com", | |
+ "dependencies": [], | |
+ "lib": "lib", | |
+ "githubName": "narwhal-mongodb", | |
+ "type": "zip", | |
+ "location": "http://github.com/mrclash/narwhal-mongodb/zipball/master" | |
} | |
} | |
} | |
\ No newline at end of file | |
diff --git a/docs/download.md b/docs/download.md | |
index 69b575e..3966c8a 100644 | |
--- a/docs/download.md | |
+++ b/docs/download.md | |
@@ -19,6 +19,22 @@ Bleeding Edge | |
Releases | |
-------- | |
-<div id="releases-list">Loading...</div> | |
-<script type="text/javascript" charset="utf-8" src="js/releases.js"></script> | |
-<script type="text/javascript" charset="utf-8" src="http://github.com/api/v2/json/repos/show/tlrobinson/narwhal/tags?callback=showreleases"></script> | |
+<div id="releases">Loading...</div> | |
+<script type="text/javascript" charset="utf-8"> | |
+ function showreleases(response) { | |
+ var releases = []; | |
+ for (var tag in response.tags) { | |
+ var tar = "http://github.com/tlrobinson/narwhal/tarball/"+tag, | |
+ zip = "http://github.com/tlrobinson/narwhal/zipball/"+tag; | |
+ commit = "http://github.com/tlrobinson/narwhal/commit/"+response.tags[tag], | |
+ tree = "http://github.com/tlrobinson/narwhal/tree/"+response.tags[tag]; | |
+ releases.push('<li>'+tag+': [<a href="'+zip+'">zip</a>][<a href="'+tar+'">tar</a>][<a href="'+tree+'">tree</a>][<a href="'+commit+'">commit</a>]</li>'); | |
+ } | |
+ releases = releases.sort(); | |
+ var reversed = []; | |
+ while (releases.length) reversed.push(releases.pop()); | |
+ | |
+ document.getElementById("releases").innerHTML = "<ul>" + reversed.join("\n") + "</ul>"; | |
+ } | |
+</script> | |
+<script type="text/javascript" charset="utf-8" src="http://github.com/api/v2/json/repos/show/tlrobinson/narwhal/tags?callback=showreleases"></script> | |
\ No newline at end of file | |
diff --git a/docs/narwhal.md b/docs/narwhal.md | |
index e3643c0..2938d43 100644 | |
--- a/docs/narwhal.md | |
+++ b/docs/narwhal.md | |
@@ -163,6 +163,10 @@ Environment Variables | |
`SHLVL` (shell level) that is the number of instances | |
of `sea` the present shell is running in. | |
+* `NARWHAL_JS_VERSION` refers to the JavaScript version, | |
+ that defaults to `"170"` for "1.7.0", and is used by | |
+ Rhino on Java to determine the valid JavaScript syntax. | |
+ | |
Configuration Files | |
------------------- | |
diff --git a/engines/default/lib/worker.js b/engines/default/lib/worker.js | |
index 4114080..d780910 100644 | |
--- a/engines/default/lib/worker.js | |
+++ b/engines/default/lib/worker.js | |
@@ -3,15 +3,15 @@ var workerEngine = require("worker-engine"); | |
var Worker = exports.Worker = function(scriptName){ | |
var worker; | |
- createWorker(scriptName, function(workerQueue, global){ | |
- worker = createPort(workerQueue, global); | |
- createPort(queue, worker, global); | |
+ createWorker(scriptName, function(workerQueue, workerGlobal){ | |
+ worker = createPort(workerQueue, workerGlobal, null, workerGlobal); | |
+ createPort(queue, worker, workerGlobal, global); | |
return worker; | |
}); | |
return worker; | |
}; | |
-function createPort(queue, target, port){ | |
+function createPort(queue, target, port, global){ | |
target.onmessage = true; // give it something to feature detect off of | |
port = port || { | |
// allows for sending a message with a direct object reference. | |
@@ -30,31 +30,21 @@ function createPort(queue, target, port){ | |
//when is supposed to be the target, and when the ports? The spec is confusing | |
target: target, | |
ports: [target], | |
- data: message.toString(), | |
+ // this can be optimized to be much faster | |
+ data: typeof message == "string" ? message : | |
+ global.JSON.parse(JSON.stringify(message)), | |
} | |
if(typeof target.onmessage == "function"){ | |
target.onmessage(event); | |
} | |
}); | |
- }; | |
- port.postData= function(message){ | |
- queue.enqueue(function(){ | |
- var event = { | |
- ports: [target], | |
- // this can be optimized to be much faster | |
- data: target.JSON.parse(JSON.stringify(message)), | |
- } | |
- if(typeof target.ondata == "function"){ | |
- target.ondata(event); | |
- } | |
- }); | |
- }; | |
+ }; | |
port.isIdle= function(){ | |
return queue.isEmpty(); | |
}; | |
return port; | |
} | |
-function createWorker(scriptName, setup){ | |
+function createWorker(scriptName, setup, workerName){ | |
var workerQueue, | |
workerGlobal = workerEngine.createEnvironment(); | |
@@ -106,7 +96,7 @@ function createWorker(scriptName, setup){ | |
} | |
} | |
- }); | |
+ }, workerName || scriptName); | |
}; | |
if(!system.__sharedWorkers__){ | |
@@ -122,14 +112,14 @@ exports.SharedWorker = function(scriptName, workerName){ | |
shared.queue = queue; | |
shared.global = global; | |
global.onconnect = true; | |
- }); | |
+ }, workerName); | |
system.__sharedWorkers__[workerName] = shared; | |
} | |
var port = {}; | |
- var returnPort = createPort(queue, port); | |
+ var returnPort = createPort(queue, port, null, global); | |
- createPort(shared.queue, returnPort, port); | |
+ createPort(shared.queue, returnPort, port, shared.global); | |
shared.queue.enqueue(function(){ | |
if(typeof shared.global.onconnect == "function"){ | |
shared.global.onconnect({ | |
diff --git a/engines/rhino/bin/narwhal-rhino b/engines/rhino/bin/narwhal-rhino | |
index 7867594..0c75631 100755 | |
--- a/engines/rhino/bin/narwhal-rhino | |
+++ b/engines/rhino/bin/narwhal-rhino | |
@@ -33,6 +33,10 @@ if [ "$(which cygpath 2>/dev/null)" ]; then | |
export NARWHAL_ENGINE_HOME=$(cygpath -wa -- "$NARWHAL_ENGINE_HOME") | |
fi | |
+if [ -z "$NARWHAL_JS_VERSION" ]; then | |
+ NARWHAL_JS_VERSION=170 | |
+fi | |
+ | |
if [ -z "$NARWHAL_DEBUGGER" ] || [ "$NARWHAL_DEBUGGER" -eq 0 ]; then | |
JAVA_MAIN=org.mozilla.javascript.tools.shell.Main | |
else | |
@@ -59,6 +63,6 @@ if [ $# -lt 1 ]; then | |
fi | |
$RLWRAP java $NARWHAL_JAVA_ARGUMENTS -cp "$BOOTCLASSPATH:$CLASSPATH" "$JAVA_MAIN" -f "$BOOTSTRAP" -f - | |
else | |
- java $NARWHAL_JAVA_ARGUMENTS -cp "$BOOTCLASSPATH:$CLASSPATH" "$JAVA_MAIN" "$BOOTSTRAP" "$0" "$@" | |
+ java $NARWHAL_JAVA_ARGUMENTS -cp "$BOOTCLASSPATH:$CLASSPATH" "$JAVA_MAIN" -version "$NARWHAL_JS_VERSION" "$BOOTSTRAP" "$0" "$@" | |
fi | |
diff --git a/engines/rhino/bin/narwhal-rhino.cmd b/engines/rhino/bin/narwhal-rhino.cmd | |
index 68c5e21..a0d5948 100755 | |
--- a/engines/rhino/bin/narwhal-rhino.cmd | |
+++ b/engines/rhino/bin/narwhal-rhino.cmd | |
@@ -18,10 +18,10 @@ if not "%NARWHAL_CLASSPATH%" == "" ( | |
set CLASSPATH=%NARWHAL_CLASSPATH%;%CLASSPATH% | |
) | |
-if not "%NARWHAL_DEBUGGER%" == "" ( | |
+if "%NARWHAL_DEBUGGER%" == "" ( | |
set JAVA_MAIN=org.mozilla.javascript.tools.shell.Main | |
) | |
-if "%NARWHAL_DEBUGGER%" == "" ( | |
+if not "%NARWHAL_DEBUGGER%" == "" ( | |
set JAVA_MAIN=org.mozilla.javascript.tools.debugger.Main | |
) | |
diff --git a/engines/rhino/bootstrap.js b/engines/rhino/bootstrap.js | |
index cd0c08c..6532a41 100644 | |
--- a/engines/rhino/bootstrap.js | |
+++ b/engines/rhino/bootstrap.js | |
@@ -31,7 +31,7 @@ | |
enginePrefix = String(Packages.java.lang.System.getenv("NARWHAL_ENGINE_HOME") || ""); | |
} | |
- var prefixes = [enginePrefix, prefix]; | |
+ var prefixes = [prefix, enginePrefix]; | |
var isFile = function (path) { | |
try { return new java.io.File(path).isFile(); } catch (e) {} | |
diff --git a/engines/rhino/lib/os-engine.js b/engines/rhino/lib/os-engine.js | |
index d19cb41..739fe7c 100644 | |
--- a/engines/rhino/lib/os-engine.js | |
+++ b/engines/rhino/lib/os-engine.js | |
@@ -3,14 +3,15 @@ var io = require('io'); | |
var cLib; | |
var getCLib = function () { | |
- if (!cLib) { | |
- var jna = Packages.com.sun.jna; | |
- cLib = jna.NativeLibrary.getInstance( | |
- jna.Platform.isWindows() ? "msvcrt" : "c" | |
- ); | |
- } | |
+ var jna = Packages.com.sun.jna; | |
+ cLib = jna.NativeLibrary.getInstance( | |
+ jna.Platform.isWindows() ? "msvcrt" : "c" | |
+ ); | |
+ getCLib = function () { | |
+ return cLib; | |
+ }; | |
return cLib; | |
-} | |
+}; | |
exports.exit = function (status) { | |
Packages.java.lang.System.exit(status << 0); | |
@@ -28,8 +29,10 @@ exports.exec = function () { | |
var cSystem; | |
var getCSystem = function () { | |
- if (!cSystem) | |
- cSystem = getCLib().getFunction("system"); | |
+ cSystem = getCLib().getFunction("system"); | |
+ getCSystem = function () { | |
+ return cSystem; | |
+ }; | |
return cSystem; | |
}; | |
diff --git a/engines/rhino/lib/worker-engine.js b/engines/rhino/lib/worker-engine.js | |
index 03f8fe8..0dcacb3 100644 | |
--- a/engines/rhino/lib/worker-engine.js | |
+++ b/engines/rhino/lib/worker-engine.js | |
@@ -14,8 +14,8 @@ exports.createEnvironment = function(){ | |
return workerGlobal; | |
}; | |
-exports.spawn = function(functionToRun){ | |
- (new java.lang.Thread(functionToRun)).start(); | |
+exports.spawn = function(functionToRun, threadName){ | |
+ (new java.lang.Thread(functionToRun, threadName)).start(); | |
}; | |
exports.defaultErrorReporter = function(e){ | |
diff --git a/engines/template/bootstrap.js b/engines/template/bootstrap.js | |
index 05994f4..3f850a5 100644 | |
--- a/engines/template/bootstrap.js | |
+++ b/engines/template/bootstrap.js | |
@@ -5,6 +5,7 @@ | |
var isFile = /*TODO*/; // function(path:string):boolean | |
var prefix = "/path/to/narwhal"; /*TODO*/ | |
+ var enginePrefix = "/path/to/engine"; /*TODO*/ | |
eval(read(prefix + "/narwhal.js"))({ | |
global: this, | |
@@ -29,6 +30,7 @@ | |
isFile: isFile | |
}, | |
prefix: prefix, | |
+ prefixes: [prefix, enginePrefix], | |
debug: false, | |
verbose: false | |
}); | |
diff --git a/lib/http-client.js b/lib/http-client.js | |
index 4d27c1b..dc43731 100644 | |
--- a/lib/http-client.js | |
+++ b/lib/http-client.js | |
@@ -28,7 +28,7 @@ var transaction = (function () { | |
function HttpClient (settings) { | |
if (!(this instanceof HttpClient)) return new HttpClient(settings); | |
if (!this.txId) this.create(); | |
- if (settings) this.set(settings); | |
+ if (settings) this.setOptions(settings); | |
}; | |
HttpClient.prototype = { | |
@@ -36,7 +36,7 @@ HttpClient.prototype = { | |
// clean up, set up defaults. | |
transaction(this.txId, true); | |
this.txId = newTransactionId(); | |
- this.set({ | |
+ this.setOptions({ | |
"method" : "GET", | |
"headers" : {}, | |
"body" : [] | |
@@ -53,10 +53,10 @@ HttpClient.prototype = { | |
var guts = transaction(this.txId); | |
switch (key) { | |
case "headers": | |
- if (typeof settings.headers !== 'object') throw new Error( | |
+ if (typeof val !== 'object') throw new Error( | |
"HttpClient: headers must be a simple object." | |
); | |
- return this.setHeaders(settings.headers); | |
+ return this.setHeaders(val); | |
case "body": | |
if (typeof val.forEach !== 'function') throw new Error( | |
"HttpClient: body must be iterable." | |
diff --git a/lib/narwhal/server-test.js b/lib/narwhal/server-test.js | |
index 138b4fa..1018728 100644 | |
--- a/lib/narwhal/server-test.js | |
+++ b/lib/narwhal/server-test.js | |
@@ -2,5 +2,5 @@ var Q = require("ref-send"); | |
Q.when(require.async("util"), function (util) { | |
print("Hello, World!"); | |
print(util.keys({"a": 10, "b": 20}).join(', ')); | |
- //alert(util.upper('hi')); | |
+ alert(util.upper('hi')); | |
}); | |
diff --git a/lib/narwhal/server.js b/lib/narwhal/server.js | |
index ddbc20a..f890e9f 100644 | |
--- a/lib/narwhal/server.js | |
+++ b/lib/narwhal/server.js | |
@@ -47,7 +47,7 @@ exports.Bundler = function (system) { | |
var depends = []; | |
loader.fetch(baseId).replace( | |
// TODO proper recursive descent parser | |
- /require\s*\(\s*(['"])([^'"]+)\1\s*\)/g, | |
+ /(?:^|\s+|;)require\s*\(\s*(['"])([^'"]+)\1\s*\)/g, | |
function (all, quote, id) { | |
depends.push(loader.resolve(id, baseId)); | |
return all; | |
diff --git a/lib/narwhal/tusk.js b/lib/narwhal/tusk.js | |
index 345e32d..37d82cf 100644 | |
--- a/lib/narwhal/tusk.js | |
+++ b/lib/narwhal/tusk.js | |
@@ -27,8 +27,7 @@ parser.command('remove', null) | |
parser.command('update', module.id + '/update'); | |
-parser.command('search', null) | |
- .help('searches the package catalog'); | |
+parser.command('search', module.id + '/search'); | |
parser.command('init', module.id + '/init'); | |
@@ -89,6 +88,7 @@ exports.readCatalog = function () { | |
var catalog = json.decode(catalogPath.read({charset: 'utf-8'})); | |
if (catalog.version === undefined || +catalog.version < minCatalogVersion) | |
throw new Error("catalog is out of date. use tusk update or create-catalog"); | |
+ packages.normalize(catalog.packages); | |
return catalog; | |
}; | |
diff --git a/lib/narwhal/tusk/catalog.js b/lib/narwhal/tusk/catalog.js | |
index 5d0ed2f..b0eb91a 100644 | |
--- a/lib/narwhal/tusk/catalog.js | |
+++ b/lib/narwhal/tusk/catalog.js | |
@@ -11,7 +11,7 @@ parser.action(function (options) { | |
var self = this; | |
if (!tusk.getCatalogPath().isFile()) | |
require('./update').update.call(this, options); | |
- util.forEachApply(util.items(tusk.readCatalog().packages), function (name, info) { | |
+ util.forEachApply(tusk.readCatalog().packages, function (name, info) { | |
name = info.name || name; | |
self.print( | |
"\0green(" + name + "\0)" + | |
diff --git a/lib/narwhal/tusk/search.js b/lib/narwhal/tusk/search.js | |
index e69de29..4c13d27 100644 | |
--- a/lib/narwhal/tusk/search.js | |
+++ b/lib/narwhal/tusk/search.js | |
@@ -0,0 +1,145 @@ | |
+ | |
+var tusk = require("../tusk"); | |
+var util = require("util"); | |
+var http = require("http"); | |
+var packages = require("packages"); | |
+var stream = require("term").stream; | |
+ | |
+var Parser = exports.Parser = function () { | |
+}; | |
+ | |
+Parser.prototype.act = function (args, options) { | |
+ this._action(args, options); | |
+}; | |
+ | |
+Parser.prototype._action = function (args, options) { | |
+ var command = args.shift(); | |
+ var packages = tusk.readCatalog().packages; | |
+ index(packages); | |
+ var predicate = Or(args); | |
+ var results = util.values(packages).map(function (info) { | |
+ return [predicate(info), info]; | |
+ }).filter(function (pair) { | |
+ return pair[0] != 0; | |
+ }); | |
+ util.sort(results); | |
+ util.forEachApply(results, function (score, info) { | |
+ stream.print( | |
+ "\0green(" + info.name + "\0)" + | |
+ (info.description ? ": " + info.description : "") | |
+ ); | |
+ }); | |
+ options.acted = true; | |
+}; | |
+ | |
+var index = function (packages) { | |
+ util.forEachApply(packages, function (name, info) { | |
+ if (!info.name) { | |
+ info.name = name; | |
+ } | |
+ if (!info.fullText) { | |
+ info.fullText = [ | |
+ info.name | |
+ ].concat(info.keywords).concat([ | |
+ info.description | |
+ ]).join(" "); | |
+ } | |
+ }); | |
+ return packages; | |
+} | |
+ | |
+var Text = function (args) { | |
+ args = args.map(function (arg) { | |
+ return new RegExp( | |
+ "\\b" + RegExp.escape(arg) + "\\b", | |
+ "i" | |
+ ); | |
+ }); | |
+ return function (info) { | |
+ var accumulator = undefined; | |
+ return Math.min.apply(this, args.map(function (arg) { | |
+ return info.fullText.search(arg) + 1; | |
+ })); | |
+ } | |
+}; | |
+ | |
+var Terms = function (args) { | |
+ for (var length = 0; length < args.length; length++) | |
+ if (args[length] == "--") | |
+ break; | |
+ if (length) { | |
+ if (/^--/.test(args[0])) { | |
+ var pattern = args.shift().match(/^--([^=]+)(?:=(.*))?/).slice(1); | |
+ var key = pattern[0]; | |
+ var value = pattern[1]; | |
+ if (!!value) { | |
+ args.unshift(value); | |
+ } | |
+ var parts = key.split("."); | |
+ return function (info) { | |
+ parts.forEach(function (part) { | |
+ if (Array.isArray(info)) { | |
+ info = info.map(function (node) { | |
+ if (node) | |
+ return node[part]; | |
+ }); | |
+ } else if (info) { | |
+ info = info[part]; | |
+ } | |
+ }); | |
+ var value = args[0]; | |
+ if (Array.isArray(info)) { | |
+ return util.has(info, value); | |
+ } else { | |
+ return info == value; | |
+ } | |
+ } | |
+ } else if (/^-/.test(args[0])) { | |
+ throw new Error("Option " + args[0] + " not recognized."); | |
+ } else { | |
+ return Text(args); | |
+ } | |
+ } else { | |
+ return Text(args); | |
+ } | |
+}; | |
+ | |
+// - recursive descent scanner | |
+// - divide and conquor | |
+ | |
+var BinaryOperator = function (Low, High, _, __) { | |
+ return function Self(args) { | |
+ var length = args.length; | |
+ for (var i = 0; i < length; i++) | |
+ if (args[i] == "--") | |
+ break; | |
+ while (i >= 0) { | |
+ i--; | |
+ var arg = args[i]; | |
+ if (arg == _ || arg == __) { | |
+ var left = Self(args.slice(0, i)); | |
+ var right = High(args.slice(i + 1)); | |
+ return function () { | |
+ return Low( | |
+ left.apply(this, arguments), | |
+ right.apply(this, arguments) | |
+ ); | |
+ } | |
+ } | |
+ } | |
+ return High(args); | |
+ } | |
+} | |
+ | |
+var And = BinaryOperator(function (lhs, rhs) { | |
+ return lhs * rhs; | |
+}, Terms, '-a', '--and'); | |
+ | |
+var Or = BinaryOperator(function (lhs, rhs) { | |
+ return lhs || rhs ? lhs + rhs : 0; | |
+}, And, '-o', '--or'); | |
+ | |
+Parser.prototype._help = "{keyword}, --and, --or, --{key} {value}"; | |
+ | |
+exports.parser = new Parser(); | |
+ | |
diff --git a/lib/packages.js b/lib/packages.js | |
index 53d0dc8..4a99164 100644 | |
--- a/lib/packages.js | |
+++ b/lib/packages.js | |
@@ -39,6 +39,9 @@ exports.load = function (prefixes) { | |
exports.verify(catalog); | |
+ // normalize data in the catalog, like Author objects | |
+ exports.normalize(catalog); | |
+ | |
// a topological sort of the packages based on their | |
// stated dependencies and contained engine-specific | |
// components | |
@@ -140,15 +143,6 @@ exports.read = function read(prefixes, catalog) { | |
catalog[name] = packageDatum; | |
packageDatum.directory = packageDirectory.join(''); | |
- // normalize authors | |
- if (packageDatum.author) | |
- packageDatum.author = new exports.Author(packageDatum.author); | |
- if (!packageDatum.contributors) | |
- packageDatum.contributors = []; | |
- packageDatum.contributors = packageDatum.contributors.map(function (contributor) { | |
- return new exports.Author(contributor); | |
- }); | |
- | |
// enqueue sub packages | |
var packagesDirectories = packageDatum.packages; | |
if (typeof packagesDirectories == "string") | |
@@ -353,6 +347,41 @@ exports.addJsPaths = function addJsPaths(jsPaths) { | |
); | |
}; | |
+/*** normalize | |
+*/ | |
+exports.normalize = function (catalog) { | |
+ for (var name in catalog) { | |
+ if (Object.prototype.hasOwnProperty.call(catalog, name)) { | |
+ exports.normalizePackage(catalog[name]); | |
+ } | |
+ } | |
+}; | |
+ | |
+/*** normalizePackage | |
+*/ | |
+exports.normalizePackage = function (info) { | |
+ | |
+ var names = []; | |
+ // normalize authors | |
+ if (!info.contributors) | |
+ info.contributors = []; | |
+ info.contributors = info.contributors.map(function (contributor) { | |
+ var author = new exports.Author(contributor); | |
+ names.push(author.name) | |
+ return author; | |
+ }); | |
+ | |
+ ['maintainer', 'author'].forEach(function (name) { | |
+ if (info[name]) | |
+ info[name] = new exports.Author(info[name]); | |
+ if (names.indexOf(name) < 0) | |
+ info.contributors.unshift(info[name]); | |
+ }); | |
+ | |
+}; | |
+ | |
+/*** Author | |
+*/ | |
exports.Author = function (author) { | |
if (!(this instanceof exports.Author)) | |
return new exports.Author(author); | |
diff --git a/lib/promise.js b/lib/promise.js | |
index 353ac38..1e31cd4 100644 | |
--- a/lib/promise.js | |
+++ b/lib/promise.js | |
@@ -145,7 +145,7 @@ function Deferred(){ | |
} | |
var newResult = func(result); | |
} | |
- if(newResult instanceof Promise){ | |
+ if(newResult && typeof newResult.then === "function"){ | |
newResult.then(function(result){ | |
listener.deferred.resolve(result); | |
}, | |
@@ -198,13 +198,13 @@ function Deferred(){ | |
function perform(value, async, sync, promiseNotNeeded){ | |
try{ | |
- if(value instanceof Promise){ | |
+ if(value && typeof value.then === "function"){ | |
value = async(value); | |
} | |
else{ | |
value = sync(value); | |
} | |
- if(value instanceof Promise){ | |
+ if(value && typeof value.then === "function"){ | |
return value; | |
} | |
if(promiseNotNeeded){ | |
@@ -321,7 +321,7 @@ exports.wait = function(target){ | |
if(!queue){ | |
throw new Error("Can not wait, the event-queue module is not available"); | |
} | |
- if(target instanceof Promise){ | |
+ if(target && typeof target.then === "function"){ | |
var isFinished, isError, result; | |
target.then(function(value){ | |
isFinished = true; | |
diff --git a/lib/sha256.js b/lib/sha256.js | |
index bb533c9..e704c79 100644 | |
--- a/lib/sha256.js | |
+++ b/lib/sha256.js | |
@@ -38,12 +38,12 @@ var K = [ | |
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 | |
]; | |
-var HASH = [ | |
- 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, | |
- 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 | |
-]; | |
- | |
var core = function (m, l) { | |
+ var HASH = [ | |
+ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, | |
+ 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 | |
+ ]; | |
+ | |
var W = []; | |
var a, b, c, d, e, f, g, h, i, j; | |
var T1, T2; | |
@@ -51,7 +51,7 @@ var core = function (m, l) { | |
m[l >> 5] |= 0x80 << (24 - l % 32); | |
m[((l + 64 >> 9) << 4) + 15] = l; | |
- for ( var i = 0; i<m.length; i+=16 ) { | |
+ for ( i = 0; i<m.length; i+=16 ) { | |
a = HASH[0]; | |
b = HASH[1]; | |
c = HASH[2]; | |
@@ -61,7 +61,7 @@ var core = function (m, l) { | |
g = HASH[6]; | |
h = HASH[7]; | |
- for ( var j = 0; j<64; j++) { | |
+ for ( j = 0; j<64; j++) { | |
if (j < 16) W[j] = m[j + i]; | |
else W[j] = struct.addU32(Gamma1256(W[j - 2]), W[j - 7], Gamma0256(W[j - 15]), W[j - 16]); | |
diff --git a/lib/util.js b/lib/util.js | |
index 58284c9..a501fbf 100644 | |
--- a/lib/util.js | |
+++ b/lib/util.js | |
@@ -155,11 +155,36 @@ exports.object.repr = function (object) { | |
// array | |
exports.array = function (array) { | |
- if (!exports.isArrayLike(array)) | |
- return exports.items(array); | |
+ if (exports.no(array)) | |
+ return []; | |
+ if (!exports.isArrayLike(array)) { | |
+ if ( | |
+ array.toArray && | |
+ !Object.prototype.hasOwnProperty.call(array, 'toArray') | |
+ ) { | |
+ return array.toArray(); | |
+ } else if ( | |
+ array.forEach && | |
+ !Object.prototype.hasOwnProperty.call(array, 'forEach') | |
+ ) { | |
+ var results = []; | |
+ array.forEach(function (value) { | |
+ results.push(value); | |
+ }); | |
+ return results; | |
+ } else { | |
+ return exports.items(array); | |
+ } | |
+ } | |
return Array.prototype.slice.call(array); | |
}; | |
+exports.array.coerce = function (array) { | |
+ if (!Array.isArray(array)) | |
+ return exports.array(array); | |
+ return array; | |
+}; | |
+ | |
exports.isArrayLike = function(object) { | |
return Array.isArray(object) || exports.isArguments(object); | |
}; | |
@@ -397,19 +422,32 @@ exports.range = function () { | |
}; | |
exports.forEach = function (array, block) { | |
- Array.prototype.forEach.call(array, block); | |
+ Array.prototype.forEach.call( | |
+ exports.array.coerce(array), | |
+ block | |
+ ); | |
}; | |
exports.forEachApply = function (array, block) { | |
- Array.prototype.forEach.call(array, exports.apply(block)); | |
+ Array.prototype.forEach.call( | |
+ exports.array.coerce(array), | |
+ exports.apply(block) | |
+ ); | |
}; | |
exports.map = function (array, block, context) { | |
- return Array.prototype.map.call(array, block, context); | |
+ return Array.prototype.map.call( | |
+ exports.array.coerce(array), | |
+ block, | |
+ context | |
+ ); | |
}; | |
exports.mapApply = function (array, block) { | |
- return Array.prototype.map.call(array, exports.apply(block)); | |
+ return Array.prototype.map.call( | |
+ exports.array.coerce(array), | |
+ exports.apply(block) | |
+ ); | |
}; | |
exports.every = exports.operator('every', 2, function (array, block, context) { | |
@@ -421,6 +459,7 @@ exports.some = exports.operator('some', 2, function (array, block, context) { | |
}); | |
exports.all = exports.operator('all', 1, function (array) { | |
+ array = exports.array.coerce(array); | |
for (var i = 0; i < array.length; i++) | |
if (!array[i]) | |
return false; | |
@@ -428,6 +467,7 @@ exports.all = exports.operator('all', 1, function (array) { | |
}); | |
exports.any = exports.operator('all', 1, function (array) { | |
+ array = exports.array.coerce(array); | |
for (var i = 0; i < array.length; i++) | |
if (array[i]) | |
return true; | |
@@ -435,10 +475,12 @@ exports.any = exports.operator('all', 1, function (array) { | |
}); | |
exports.reduce = exports.operator('reduce', 2, function (array, block, basis) { | |
+ array = exports.array.coerce(array); | |
return array.reduce.apply(array, arguments); | |
}); | |
exports.reduceRight = exports.operator('reduceRight', 2, function (array, block, basis) { | |
+ array = exports.array.coerce(array); | |
return array.reduceRight.apply(array, arguments); | |
}); | |
@@ -447,6 +489,7 @@ exports.zip = function () { | |
}; | |
exports.transpose = function (array) { | |
+ array = exports.array.coerce(array); | |
var transpose = []; | |
var length = Math.min.apply(this, exports.map(array, function (row) { | |
return row.length; | |
@@ -464,6 +507,7 @@ exports.transpose = function (array) { | |
}; | |
exports.enumerate = function (array, start) { | |
+ array = exports.array.coerce(array); | |
if (exports.no(start)) | |
start = 0; | |
return exports.zip( | |
diff --git a/narwhal.js b/narwhal.js | |
index b99b0b4..9e8ef52 100644 | |
--- a/narwhal.js | |
+++ b/narwhal.js | |
@@ -55,7 +55,7 @@ for (var name in system.fs) { | |
} | |
} | |
system.fs = fs; | |
-system.enginePrefix = system.prefix + '/engines/' + system.engines[0]; | |
+system.enginePrefix = system.enginePrefix || system.prefix + '/engines/' + system.engines[0]; | |
// construct the initial paths | |
var paths = []; | |
// XXX system.packagePrefixes deprecated in favor of system.prefixes | |
diff --git a/package.json b/package.json | |
index 35f7273..0b0e0fd 100644 | |
--- a/package.json | |
+++ b/package.json | |
@@ -18,7 +18,8 @@ | |
"Mark Porter", | |
"Isaac Z. Schlueter (http://blog.izs.me/)", | |
"Kris Zyp (http://www.sitepen.com/blog/author/kzyp/)", | |
- "Nathan Stott (http://nathan.whiteboard-it.com) <nathan.stott@whiteboard-it.com>" | |
+ "Nathan Stott (http://nathan.whiteboard-it.com) <nathan.stott@whiteboard-it.com>", | |
+ "Toby Ho (http://tobyho.com) <airportyh@gmail.com>" | |
], | |
"main": "examples/narwhal", | |
"lib": ["lib"], | |
diff --git a/sources.json b/sources.json | |
index e04535e..43e515c 100644 | |
--- a/sources.json | |
+++ b/sources.json | |
@@ -162,6 +162,10 @@ | |
"type": "github", | |
"user": "nrstott" | |
}, | |
+ "json-template": { | |
+ "type": "github", | |
+ "user": "Gozala" | |
+ }, | |
"ejs": { | |
"type": "github", | |
"user": "nrstott", | |
@@ -171,6 +175,11 @@ | |
"type": "github", | |
"user": "nrstott", | |
"name": "narwhal-couchdb" | |
+ }, | |
+ "mongodb": { | |
+ "type": "github", | |
+ "user": "mrclash", | |
+ "name": "narwhal-mongodb" | |
} | |
} | |
} | |
diff --git a/tests/commonjs/file/dirname.js b/tests/commonjs/file/dirname.js | |
index 197b80c..2a075ce 100644 | |
--- a/tests/commonjs/file/dirname.js | |
+++ b/tests/commonjs/file/dirname.js | |
@@ -4,12 +4,21 @@ var assert = require('test/assert'); | |
var fs = require('file'); | |
util.forEachApply([ | |
+ // relative | |
['', '.'], | |
['.', '.'], | |
['foo', '.'], | |
- //['foo/', '.'], | |
- ['foo/bar', 'foo'] | |
+ ['foo/', '.'], | |
+ ['foo/bar', 'foo'], | |
+ ['foo/bar/', 'foo'], | |
+ // absolute | |
+ ["/", "/"], | |
+ ["/foo", "/"], | |
+ ["/foo/", "/"], | |
+ ["/foo/bar", "/foo"], | |
+ ["/foo/bar/", "/foo"] | |
// TODO: many more tests | |
+ // TODO: Windows tests | |
], function (path, expected) { | |
exports['test ' + util.repr(path)] = function () { | |
var actual = fs.dirname(path); | |
diff --git a/tests/commonjs/file/glob.js b/tests/commonjs/file/glob.js | |
index 70faea8..c50cf37 100644 | |
--- a/tests/commonjs/file/glob.js | |
+++ b/tests/commonjs/file/glob.js | |
@@ -437,3 +437,7 @@ exports["tests recursively matches directories with '**/<characters>'"] = functi | |
assert.eq(expected, dir.glob('**/*fil?{,.}*').sort()); | |
}); | |
} | |
+ | |
+if (require.main == module.id) | |
+ require("os").exit(require("test/runner").run(exports)) | |
+ | |
diff --git a/tests/commonjs/file/path.js b/tests/commonjs/file/path.js | |
new file mode 100644 | |
index 0000000..111a395 | |
--- /dev/null | |
+++ b/tests/commonjs/file/path.js | |
@@ -0,0 +1,17 @@ | |
+ | |
+var assert = require("test/assert"); | |
+var file = require("file"); | |
+var util = require("util"); | |
+ | |
+util.forEachApply([ | |
+ ["/", "a", "/a"], | |
+ [".", "a", "./a"] | |
+], function (path, rel, expected) { | |
+ exports['test path.join ' + util.repr(arguments)] = function () { | |
+ assert.eq(expected, system.fs.path(path).join(rel)); | |
+ }; | |
+}); | |
+ | |
+if (require.main === module.id) | |
+ require("os").exit(require("test/runner").run(exports)); | |
+ | |
diff --git a/tests/commonjs/file/relative.js b/tests/commonjs/file/relative.js | |
index 5ec5a84..c9102fc 100644 | |
--- a/tests/commonjs/file/relative.js | |
+++ b/tests/commonjs/file/relative.js | |
@@ -17,6 +17,10 @@ util.forEachApply([ | |
['a/b', '..', '../../'], | |
['a/b', 'c', '../c'], | |
['a/b', 'c/d', '../c/d'], | |
+ // XXX the next two are disputed - kriskowal | |
+ ["a", "a/b/c", "b/c"], | |
+ ["a/", "a/b/c", "b/c"] | |
+ | |
], function (source, target, expected) { | |
var name = ( | |
util.repr(source) + ' -> ' + util.repr(target) + | |
diff --git a/tests/util/array.js b/tests/util/array.js | |
index 77c6bfe..8aff5f7 100644 | |
--- a/tests/util/array.js | |
+++ b/tests/util/array.js | |
@@ -18,6 +18,38 @@ exports.testArrayObject = function () { | |
assert.eq([["a", 10], ["b", 20]], util.array({"a": 10, "b": 20})); | |
}; | |
+exports.testArrayPolymorphicToArray = function () { | |
+ var Type = function () { | |
+ }; | |
+ Type.prototype.toArray = function () { | |
+ return [1]; | |
+ }; | |
+ assert.eq([1], util.array(new Type())); | |
+}; | |
+ | |
+exports.testArrayPolymorphicToArrayNegative = function () { | |
+ var toArray = function () {}; | |
+ assert.eq([["toArray", toArray]], util.array({ | |
+ "toArray": toArray | |
+ })); | |
+}; | |
+ | |
+exports.testArrayPolymorphicForEach = function () { | |
+ var Type = function () { | |
+ }; | |
+ Type.prototype.forEach = function (block) { | |
+ block(1); | |
+ }; | |
+ assert.eq([1], util.array(new Type())); | |
+}; | |
+ | |
+exports.testArrayPolymorphicForEachNegative = function () { | |
+ var forEach = function () {}; | |
+ assert.eq([["forEach", forEach]], util.array({ | |
+ "forEach": forEach | |
+ })); | |
+}; | |
+ | |
exports.testIsArguments = require("./array/is-arguments"); | |
exports.testIsArrayLike = require("./array/is-array-like"); | |
@@ -105,7 +137,22 @@ exports.testForEach = function () { | |
exports.testForEachApply = function () { | |
}; | |
+*/ | |
+ | |
+exports.testForEachApplyPolymorphicForEach = function () { | |
+ var Type = function () { | |
+ }; | |
+ Type.prototype.forEach = function (block) { | |
+ block([1]); | |
+ }; | |
+ var collect = []; | |
+ util.forEachApply(new Type(), function (n) { | |
+ collect.push(n); | |
+ }); | |
+ assert.eq([1], collect); | |
+}; | |
+/* | |
exports.testMap = function () { | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment