Skip to content

Instantly share code, notes, and snippets.

@kriskowal
Created October 28, 2009 21:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kriskowal/220846 to your computer and use it in GitHub Desktop.
Save kriskowal/220846 to your computer and use it in GitHub Desktop.
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