// Timers function setTimeout (callback, delay) { var timer = new node.Timer(callback, delay, 0); timer.start(); return timer; } function setInterval (callback, delay) { var timer = new node.Timer(callback, delay, delay); timer.start(); return timer; } function clearTimeout (timer) { timer.stop(); delete timer; } clearInterval = clearTimeout; // This is useful for dealing with raw encodings. Array.prototype.encodeUtf8 = function () { return String.fromCharCode.apply(String, this); }; node.path = new function () { this.join = function () { var joined = ""; for (var i = 0; i < arguments.length; i++) { var part = arguments[i].toString(); /* Some logic to shorten paths */ if (part === ".") continue; while (/^\.\//.exec(part)) part = part.replace(/^\.\//, ""); if (i === 0) { part = part.replace(/\/*$/, "/"); } else if (i === arguments.length - 1) { part = part.replace(/^\/*/, ""); } else { part = part.replace(/^\/*/, "") .replace(/\/*$/, "/"); } joined += part; } return joined; }; this.dirname = function (path) { if (path.charAt(0) !== "/") path = "./" + path; var parts = path.split("/"); return parts.slice(0, parts.length-1).join("/"); }; this.filename = function (path) { if (path.charAt(0) !== "/") path = "./" + path; var parts = path.split("/"); return parts[parts.length-1]; }; }; node.cat = function(location, encoding, callback) { var url_re = new RegExp("^http:\/\/"); var f = url_re.exec(location) ? node.http.cat : node.fs.cat; f(location, encoding, callback); }; // Module node.Module = function (o) { this.parent = o.parent; this.target = o.target || {}; if (!o.path) throw "path argument required"; if (o.path.charAt(0) == "/") { throw "Absolute module paths are not yet supported by Node"; } if (o.path.match(/:\/\//)) { this.filename = o.path; } else { var dir = o.base_directory || "."; this.filename = node.path.join(dir, o.path); } this.loaded = false; this.exited = false; this.children = []; }; node.Module.prototype.load = function (callback) { var self = this; if (self.loaded) { throw "Module '" + self.filename + "' is already loaded."; } node.cat(self.filename, "utf8", function (status, content) { if (status != 0) { stderr.puts("Error reading " + self.filename); node.exit(1); } self.target.__require = function (path) { return self.newChild(path, {}); }; self.target.__include = function (path) { self.newChild(path, self.target); }; // create wrapper function var wrapper = "function (__filename) {\n" + " var onLoad;\n" + " var onExit;\n" + " var exports = this;\n" + " var require = this.__require;\n" + " var include = this.__include;\n" + content + "\n" + " this.__onLoad = onLoad;\n" + " this.__onExit = onExit;\n" + "};\n" ; var compiled_wrapper = node.compile(wrapper, self.filename); compiled_wrapper.apply(self.target, [self.filename]); self.onLoad = self.target.__onLoad; self.onExit = self.target.__onExit; self.loadChildren(function () { if (self.onLoad) self.onLoad(); self.loaded = true; if (callback) callback(); }); }); }; node.Module.prototype.newChild = function (path, target) { var child = new node.Module({ target: target, path: path, base_directory: node.path.dirname(this.filename), parent: this }); this.children.push(child); return target; }; node.Module.prototype.loadChildren = function (callback) { var children = this.children; if (children.length == 0 && callback) callback(); var nloaded = 0; for (var i = 0; i < children.length; i++) { var child = children[i]; child.load(function () { nloaded += 1; if (nloaded == children.length && callback) callback(); }); } }; node.Module.prototype.exitChildren = function (callback) { var children = this.children; if (children.length == 0 && callback) callback(); var nexited = 0; for (var i = 0; i < children.length; i++) { children[i].exit(function () { nexited += 1; if (nexited == children.length && callback) callback(); }); } }; node.Module.prototype.exit = function (callback) { var self = this; if (self.exited) { throw "Module '" + self.filename + "' is already exited."; } this.exitChildren(function () { if (self.onExit) self.onExit(); self.exited = true; if (callback) callback() }); }; (function () { // Load the root module--the command line argument. root_module = new node.Module({ path: node.path.filename(ARGV[1]), base_directory: node.path.dirname(ARGV[1]), target: this }); root_module.load(); node.exit = function (code) { root_module.exit(function () { node.reallyExit(code); }); }; }())