Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial commit - node_modules and an example without promises

  • Loading branch information...
commit bf44e20d954a41dbd0dcb19437e319494462448f 0 parents
@dominykas dominykas authored
31 00-withoutPromises.js
@@ -0,0 +1,31 @@
+if (typeof define !== 'function') { var define = require('amdefine')(module); }
+
+define(["fs", "path"], function(fs, path){
+
+ var defaultLang = "en", UTF = 'utf-8';
+
+ var getFn = function(lang, pageId)
+ {
+ return path.join("testdata", pageId+"."+lang+".html");
+ };
+
+ var getHtml = function (lang, pageId, callback)
+ {
+ fs.readFile(getFn(lang, pageId), UTF, function(e, data){
+ if (e != null) {
+ if (lang == defaultLang) {
+ callback(e, null);
+ } else {
+ getHtml(defaultLang, pageId, callback);
+ }
+ return;
+ }
+ callback(null, data);
+ });
+ };
+
+ return {
+ getHtml: getHtml
+ };
+
+});
69 00-withoutPromises.test.js
@@ -0,0 +1,69 @@
+if (typeof define !== 'function') { var define = require('amdefine')(module); }
+
+define("00-withoutPromises.test", ["buster", "fs", "./00-withoutPromises"], function(buster, fs, html) {
+
+ buster.testCase("00", {
+
+
+ "setUp": function()
+ {
+ this.fsStub = this.stub(fs, "readFile");
+ this.fsStub.withArgs("testdata/one.en.html", "utf-8").yields(null, "one english");
+ this.fsStub.withArgs("testdata/one.de.html", "utf-8").yields(null, "one german");
+ this.fsStub.withArgs("testdata/two.en.html", "utf-8").yields(null, "two english");
+ this.fsStub.withArgs("testdata/two.de.html", "utf-8").yields(new Error(), null);
+ this.fsStub.withArgs("testdata/na.en.html", "utf-8").yields(new Error(), null);
+ this.fsStub.withArgs("testdata/na.de.html", "utf-8").yields(new Error(), null);
+ },
+
+ "should read file (de, exists)": function(done)
+ {
+ html.getHtml("de", "one", function(e, data){
+
+ expect(this.fsStub).toHaveBeenCalledOnce();
+ expect(e).toBeNull();
+ expect(data).toEqual("one german");
+ done();
+
+ }.bind(this));
+ },
+
+ "should read file (de, fallback)": function(done)
+ {
+ html.getHtml("de", "two", function(e, data){
+
+ expect(this.fsStub).toHaveBeenCalledTwice();
+ expect(e).toBeNull();
+ expect(data).toEqual("two english");
+ done();
+
+ }.bind(this));
+ },
+
+ "should return error (en, na)": function(done)
+ {
+ html.getHtml("en", "na", function(e, data){
+
+ expect(this.fsStub).toHaveBeenCalledOnce();
+ expect(e).not.toBeNull();
+ expect(data).toBeNull();
+ done();
+
+ }.bind(this));
+ },
+
+ "should return error (de, na)": function(done)
+ {
+ html.getHtml("de", "na", function(e, data){
+
+ expect(this.fsStub).toHaveBeenCalledTwice();
+ expect(e).not.toBeNull();
+ expect(data).toBeNull();
+ done();
+
+ }.bind(this));
+ }
+
+ });
+
+});
13 LICENSE
@@ -0,0 +1,13 @@
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+Copyright (C) 2012 Dominykas Blyžė https://twitter.com/dymonaz
+
+Everyone is permitted to copy and distribute verbatim or modified
+copies of this license document, and changing it is allowed as long
+as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
1  README
@@ -0,0 +1 @@
+A test project for dublinjs Oct/2012 meetup - examples with TDD and promises
9 buster.js
@@ -0,0 +1,9 @@
+var config = module.exports;
+
+config["Node tests"] = {
+ rootPath:".",
+ environment:"node",
+ tests:[
+ "*.test.js"
+ ]
+};
2  node_modules/amdefine/.npmignore
@@ -0,0 +1,2 @@
+README.md
+tests/
58 node_modules/amdefine/LICENSE
@@ -0,0 +1,58 @@
+amdefine is released under two licenses: new BSD, and MIT. You may pick the
+license that best suits your development needs. The text of both licenses are
+provided below.
+
+
+The "New" BSD License:
+----------------------
+
+Copyright (c) 2011, The Dojo Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of the Dojo Foundation nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+MIT License
+-----------
+
+Copyright (c) 2011, The Dojo Foundation
+
+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.
200 node_modules/amdefine/amdefine.js
@@ -0,0 +1,200 @@
+/** vim: et:ts=4:sw=4:sts=4
+ * @license amdefine 0.0.2 Copyright (c) 2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/amdefine for details
+ */
+
+/*jslint node: true */
+/*global module, process */
+'use strict';
+
+var path = require('path'),
+ loaderCache = {},
+ makeRequire;
+
+/**
+ * Given a relative module name, like ./something, normalize it to
+ * a real name that can be mapped to a path.
+ * @param {String} name the relative name
+ * @param {String} baseName a real name that the name arg is relative
+ * to.
+ * @returns {String} normalized name
+ */
+function normalize(name, baseName) {
+ return path.normalize(path.join(baseName, name));
+}
+
+/**
+ * Create the normalize() function passed to a loader plugin's
+ * normalize method.
+ */
+function makeNormalize(relName) {
+ return function (name) {
+ return normalize(name, relName);
+ };
+}
+
+function makeLoad(id) {
+ function load(value) {
+ loaderCache[id] = value;
+ }
+
+ load.fromText = function (id, text) {
+ //This one is difficult because the text can/probably uses
+ //define, and any relative paths and requires should be relative
+ //to that id was it would be found on disk. But this would require
+ //bootstrapping a module/require fairly deeply from node core.
+ //Not sure how best to go about that yet.
+ throw new Error('amdefine does not implement load.fromText');
+ };
+
+ return load;
+}
+
+function stringRequire(module, require, id) {
+ //Split the ID by a ! so that
+ var index = id.indexOf('!'),
+ relId = path.dirname(module.filename),
+ prefix, plugin;
+
+ if (index === -1) {
+ //Straight module lookup. If it is one of the special dependencies,
+ //deal with it, otherwise, delegate to node.
+ if (id === 'require') {
+ return makeRequire(module, require);
+ } else if (id === 'exports') {
+ return module.exports;
+ } else if (id === 'module') {
+ return module;
+ } else {
+ return require(id);
+ }
+ } else {
+ //There is a plugin in play.
+ prefix = id.substring(0, index);
+ id = id.substring(index + 1, id.length);
+
+ plugin = require(prefix);
+
+ if (plugin.normalize) {
+ id = plugin.normalize(id, makeNormalize(relId));
+ } else {
+ //Normalize the ID normally.
+ id = normalize(id, relId);
+ }
+
+ if (loaderCache[id]) {
+ return loaderCache[id];
+ } else {
+ plugin.load(id, makeRequire(module, require), makeLoad(id), {});
+
+ return loaderCache[id];
+ }
+ }
+}
+
+makeRequire = function (module, require) {
+ function amdRequire(deps, callback) {
+ if (typeof deps === 'string') {
+ //Synchronous, single module require('')
+ return stringRequire(module, require, deps);
+ } else {
+ //Array of dependencies with a callback.
+
+ //Convert the dependencies to modules.
+ deps = deps.map(function (depName) {
+ return stringRequire(module, require, depName);
+ });
+
+ //Wait for next tick to call back the require call.
+ process.nextTick(function () {
+ callback.apply(null, deps);
+ });
+
+ //Keeps strict checking in komodo happy.
+ return undefined;
+ }
+ }
+
+ amdRequire.toUrl = function (filePath) {
+ if (filePath.indexOf('.') === 0) {
+ return normalize(filePath, path.dirname(module.filename));
+ } else {
+ return filePath;
+ }
+ };
+
+ return amdRequire;
+};
+
+/**
+ * Creates a define for node.
+ * @param {Object} module the "module" object that is defined by Node for the
+ * current module.
+ * @param {Function} [require]. Node's require function for the current module.
+ * It only needs to be passed in Node versions before 0.5, when module.require
+ * did not exist.
+ * @returns {Function} a define function that is usable for the current node
+ * module.
+ */
+function amdefine(module, require) {
+ var alreadyCalled = false;
+
+ //Favor explicit value, passed in if the module wants to support Node 0.4.
+ require = require || function req() {
+ return module.require.apply(module, arguments);
+ };
+
+ //Create a define function specific to the module asking for amdefine.
+ function define() {
+
+ var args = arguments,
+ factory = args[args.length - 1],
+ isFactoryFunction = (typeof factory === 'function'),
+ deps, result;
+
+ //Only support one define call per file
+ if (alreadyCalled) {
+ throw new Error('amdefine cannot be called more than once per file.');
+ }
+ alreadyCalled = true;
+
+ //Grab array of dependencies if it is there.
+ if (args.length > 1) {
+ deps = args[args.length - 2];
+ if (!Array.isArray(deps)) {
+ //deps is not an array, may be an ID. Discard it.
+ deps = null;
+ }
+ }
+
+ //If there are dependencies, they are strings, so need
+ //to convert them to dependency values.
+ if (deps) {
+ deps = deps.map(function (depName) {
+ return stringRequire(module, require, depName);
+ });
+ } else if (isFactoryFunction) {
+ //Pass in the standard require, exports, module
+ deps = [makeRequire(module, require), module.exports, module];
+ }
+
+ if (!isFactoryFunction) {
+ //Factory is an object that should just be used for the define call.
+ module.exports = factory;
+ } else {
+ //Call the factory with the right dependencies.
+ result = factory.apply(module.exports, deps);
+
+ if (result !== undefined) {
+ module.exports = result;
+ }
+ }
+ }
+
+ define.amd = {};
+
+ return define;
+}
+
+module.exports = amdefine;
27 node_modules/amdefine/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "amdefine",
+ "description": "Provide AMD's define() API for declaring modules in the AMD format",
+ "version": "0.0.2",
+ "homepage": "http://github.com/jrburke/amdefine.js",
+ "author": {
+ "name": "James Burke",
+ "email": "jrburke@gmail.com",
+ "url": "http://github.com/jrburke"
+ },
+ "licenses": [
+ {
+ "type": "BSD",
+ "url": "https://github.com/jrburke/amdefine/blob/master/LICENSE"
+ },
+ {
+ "type": "MIT",
+ "url": "https://github.com/jrburke/amdefine/blob/master/LICENSE"
+ }
+ ],
+ "main": "./amdefine.js",
+ "engines": {
+ "node": ">=0.4.2"
+ },
+ "_id": "amdefine@0.0.2",
+ "_from": "amdefine"
+}
695 node_modules/q/.tmp/makeQ.js
@@ -0,0 +1,695 @@
+// Copyright (C) 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Implements the EcmaScript
+ * http://wiki.ecmascript.org/doku.php?id=strawman:concurrency
+ * strawman, securely when run a Caja or SES platform.
+ *
+ * //provides ses.makeQ
+ * @author Mark S. Miller, based on earlier designs by Tyler Close,
+ * Kris Kowal, and Kevin Reid.
+ * @overrides ses
+ * @requires WeakMap, cajaVM
+ */
+
+var ses;
+
+(function() {
+ "use strict";
+
+ if (ses && !ses.ok()) { return; }
+
+ var bind = Function.prototype.bind;
+ // See
+ // http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
+ var uncurryThis = bind.bind(bind.call);
+
+ var bindFn = uncurryThis(bind);
+ var applyFn = uncurryThis(bind.apply);
+ var sliceFn = uncurryThis([].slice);
+ var toStringFn = uncurryThis({}.toString);
+
+ var freeze = Object.freeze;
+ var constFunc = cajaVM.constFunc;
+ var def = cajaVM.def;
+ var is = cajaVM.is;
+
+
+ /**
+ * Tests if the presumably thrown error is simply signaling the end
+ * of a generator's iteration.
+ *
+ * <p>TODO(erights): Find some way to accomodate Firefox's
+ * pre-harmony iterators, at least for pre-harmony testing. Take a
+ * look at how Kris Kowal's q library handles this.
+ *
+ * <p>See
+ * http://wiki.ecmascript.org/doku.php?id=harmony:iterators#stopiteration
+ */
+ function isStopIteration(err) {
+ return toStringFn(err) === '[object StopIteration]';
+ }
+
+
+ /**
+ * Makes a Q object which uses the provided nextTick function to
+ * postpone events to future turns.
+ */
+ function makeQ(setTimeout, nextTick) {
+ nextTick = nextTick || setTimeout;
+
+ /**
+ * Maps from promises to their handlers.
+ *
+ * <p>All handlers and the "handlers" map must never escape. A
+ * handler holds <i>all</i> the state of its promise, serving as a
+ * private state record, but more flexible in two ways we take
+ * advantage of:
+ * <ul>
+ * <li>A promise can change state and behavior by changing which
+ * handler it is associated with.
+ * <li>More than one promise can share the same handler, making them
+ * essentially identical except for identity.
+ * </ul>
+ */
+ var handlers = WeakMap();
+
+ /**
+ * Among objects, all and only promises have handlers.
+ */
+ function isPromise(value) {
+ if (value !== Object(value)) { return false; }
+ return !!handlers.get(value);
+ }
+
+ /**
+ * Get the "best" handler associated with this promise, shortening
+ * "became" chains in the process.
+ */
+ function handle(promise) {
+ var handler = handlers.get(promise);
+ if (!handler || !handler.became) { return handler; }
+ while (handler.became) {
+ handler = handler.became;
+ }
+ handlers.set(promise, handler);
+ return handler;
+ }
+
+ /**
+ * Run the thunk later in its own turn, but immediately return a
+ * promise for what its outcome will be.
+ */
+ function postpone(thunk) {
+ var result = defer();
+ nextTick(function() {
+ var value;
+ try {
+ value = thunk();
+ } catch (reason) {
+ value = reject(reason);
+ }
+ result.resolve(value);
+ });
+ return result.promise;
+ }
+
+ /**
+ * To deliver a messenger to a handler is to eventually ask the handler to
+ * dispatch on the meesage carried by the messenger, and to return the
+ * outcome to the messenger's resolver.
+ *
+ * <p>A messenger is a record with
+ * <ul>
+ * <li>OP - the name of one of the concrete handler methods spelled
+ * in all upper case, which is currently GET, POST, PUT, DELETE, and
+ * WHEN. We might add the other HTTP verbs, HEAD and OPTION. And we
+ * might add the other needed reference bookkeeping operation,
+ * WHEN_BROKEN, so that a farPromise can notify if it later breaks.
+ * <li>args - the array of arguments to use when calling the
+ * handler's OP method.
+ * <li>resolve - a resolver function, for reporting the outcome of
+ * eventually asking the handler to dispatch the messenger's message.
+ * </ul>
+ * The messenger's message consists of its OP and args.
+ *
+ * <p>A handler's dispatch method may deliver the messenger's message
+ * to this handler, buffer the messenger for later, or ask another
+ * handler to dispatch it.
+ */
+ function deliver(handler, messenger) {
+ var value;
+ nextTick(function() {
+ try {
+ value = handler.dispatch(
+ messenger.OP,
+ messenger.args
+ );
+ } catch (reason) {
+ value = reject(reason);
+ }
+ messenger.resolve(value);
+ });
+ }
+
+
+ /*************************************************************************
+ * A near promise's resolution is a non-promise.
+ *
+ * <p>"promise" must be a near promise whose handler is this
+ * handler. "target" must be a non-promise. The NearHandler
+ * constructor does not actually use its "promise" argument, but it
+ * is there to support the general HandlerConstructor API as assumed
+ * by the Promise constructor.
+ */
+ function NearHandler(promise, target) {
+ this.target = target;
+ }
+ NearHandler.prototype = {
+
+ stateName: 'near',
+
+ nearer: function() { return this.target; },
+
+ dispatch: function(OP, args) {
+ return applyFn(this[OP], this, args);
+ },
+
+ POST: function(opt_name, args) {
+ var target = this.target;
+ if (opt_name === null || opt_name === void 0) {
+ return applyFn(target, void 0, args);
+ } else {
+ return applyFn(target[opt_name], target, args);
+ }
+ },
+
+ GET: function(name) { return this.target[name]; },
+ PUT: function(name, value) { this.target[name] = value; return void 0; },
+ DELETE: function(name) { return delete this.target[name]; },
+
+ /** Just invoke sk, the success continuation */
+ WHEN:function(sk, fk) { return sk(this.target); }
+ };
+
+ /**
+ * Returns the promise form of value.
+ *
+ * <p>If value is already a promise, return it. Otherwise wrap it
+ * in a promise that is already resolved to value.
+ */
+ function Q(value) {
+ if (isPromise(value)) { return value; }
+ return new Promise(NearHandler, value);
+ }
+
+
+ /*************************************************************************
+ * A broken promise will never deliver any operations because of the
+ * stated reason.
+ *
+ * <p>"promise" must be a broken promise whose handler is this handler.
+ * "reason" will typically be a thrown Error. An originally broken
+ * promise's resolution is itself. A broken promise's resolution is
+ * a broken promise just like itself, except possibly for identity.
+ */
+ function BrokenHandler(promise, reason) {
+ this.promise = promise;
+ this.reason = reason;
+
+ this.stateName = 'broken (by ' + reason + ')';
+ }
+ BrokenHandler.prototype = {
+
+ nearer: function() { return this.promise; },
+
+ dispatch: function(OP, args) {
+ if (OP === 'WHEN') { return this.WHEN (args[0], args[1]); }
+ return this.promise;
+ },
+
+ /** Just invoke fk, the failure continuation */
+ WHEN: function(sk, fk) { return fk(this.reason); }
+ };
+
+ /**
+ * Reject makes a new broken promise which reports "reason" as the
+ * alleged reason why it is broken.
+ *
+ * <p>Does a def(reason), which (transitively under SES) freezes
+ * reason.
+ */
+ function reject(reason) {
+ reason = def(reason);
+ try {
+ return new Promise(BrokenHandler, reason);
+ } catch (err) {
+ // Workaround undiagnosed intermittent FF bug. TODO(erights):
+ // isolate and report.
+ // debugger;
+ reason = 'Failing to report error for mysterious reasons';
+ }
+ return new Promise(BrokenHandler, reason);
+ }
+
+ /**
+ * Resolving a promise to itself breaks all promises in the loop
+ * with the reason being an Error complaining of a vicious promise
+ * cycle.
+ */
+ var theViciousCycle;
+ var theViciousCycleHandler;
+
+
+ /*************************************************************************
+ * The handler for a local unresolved promise, as made by defer().
+ *
+ * <p>"promise" must be a local unresolved promise.
+ */
+ function UnresolvedHandler(promise, queue) {
+ this.promise = promise;
+ this.queue = queue;
+ }
+ UnresolvedHandler.prototype = {
+
+ stateName: 'unresolved',
+
+ nearer: function() { return this.promise; },
+
+ dispatch: function(OP, args) {
+ var result = defer();
+ this.queue({
+ resolve: result.resolve,
+ OP: OP,
+ args: args
+ });
+ return result.promise;
+ }
+ };
+
+ /**
+ * Have all promises which were using oldHandler as their handler
+ * instead use newPromise's handler as their handler.
+ *
+ * <p>oldHandler must be a become-able kind of handler, i.e., an
+ * UnresolvedHandler, FarHandler, or RemoteHandler. It also must
+ * not yet have become anything.
+ */
+ function become(oldHandler, newPromise) {
+ oldHandler.became = theViciousCycleHandler;
+ var newHandler = handle(newPromise);
+ oldHandler.became = newHandler;
+ return newHandler;
+ }
+
+ /**
+ * Returns an unresolved promise and its corresponding resolver
+ * (resolve function).
+ */
+ function defer() {
+ var buffer = [];
+ function queue(messenger) {
+ if (buffer) {
+ buffer.push(messenger);
+ } else {
+ // This case seems to have happened once but I have not yet
+ // been able to reproduce it.
+ debugger;
+ }
+ }
+ var promise = new Promise(UnresolvedHandler, queue);
+ var handler = handle(promise);
+
+ function resolve(value) {
+ if (!buffer) { return; } // silent
+ // assert(handler === handle(promise)) since, the only way this
+ // becomes untrue is by a prior call to resolve, which will
+ // clear buffer, so we would never get here.
+
+ var buf = buffer;
+ buffer = void 0;
+
+ var newHandler = become(handler, Q(value));
+ handle(promise); // just to shorten
+ handler = void 0; // A dead resolver should not retain dead objects
+ promise = void 0;
+
+ var forward;
+ if (newHandler instanceof UnresolvedHandler) {
+ // A nice optimization but not strictly necessary.
+ forward = newHandler.queue;
+ } else {
+ forward = bindFn(deliver, void 0, newHandler);
+ }
+
+ for (var i = 0, len = buf.length; i < len; i++) {
+ forward(buf[i]);
+ }
+ }
+
+ return freeze({
+ promise: promise,
+ resolve: constFunc(resolve)
+ });
+ }
+
+
+ /*************************************************************************
+ * A far promise is a fulfilled promise to a possibly remote
+ * object whose behavior is locally represented by a farDispatch
+ * function.
+ *
+ * <p>The farDispatch function acts like the dispatch method of the
+ * FarHandler, except that it gets only the HTTP verb operations,
+ * not the WHEN operation.
+ *
+ * <p>To support the reporting of partition, for those farDispatches
+ * whose failure model makes partition visible, a far promise may
+ * become broken.
+ */
+ function FarHandler(promise, dispatch) {
+ this.promise = promise;
+ this.dispatch = dispatch;
+ }
+ FarHandler.prototype = {
+ stateName: 'far',
+
+ nearer: function() { return this.promise; },
+
+ /** Just invoke sk, the success continuation */
+ WHEN: function(sk, fk) { return sk(this.promise); }
+ };
+
+ function makeFar(farDispatch, nextSlotP) {
+ var farPromise;
+
+ function dispatch(OP, args) {
+ if (OP === 'WHEN') { return farPromise.WHEN(args[0], args[1]); }
+ return farDispatch(OP, args);
+ }
+ farPromise = new Promise(FarHandler, dispatch);
+
+
+ function breakFar(reason) {
+ // Note that a farPromise is resolved, so its nearer()
+ // identity must be stable, even when it becomes
+ // broken. Thus, we do not become(farHandler, reject(reason))
+ // or become(farHandler, nextSlot.value). Rather, we switch
+ // to a new broken handler whose promise is this same
+ // farPromise.
+ var farHandler = handle(farPromise);
+ var brokenHandler = new BrokenHandler(farPromise, reason);
+ handlers.set(farPromise, brokenHandler);
+ become(farHandler, farPromise);
+ }
+
+ Q(nextSlotP).get('value').when(function(v) {
+ breakFar(new Error('A farPromise can only further resolve to broken'));
+ }, breakFar).end();
+
+ return farPromise;
+ };
+
+
+ /*************************************************************************
+ * A remote promise is an unresolved promise with a possibly remote
+ * resolver, where the behavior of sending a message to a remote
+ * promise may be to send the message to that destination (e.g. for
+ * promise pipelining). The actual behavior is locally represented
+ * by a remoteDispatch function.
+ *
+ * <p>The remoteDispatch function acts like the dispatch method of the
+ * RemoteHandler, except that it gets only the HTTP verb operations,
+ * not the WHEN operation. Instead, the WHEN operations are
+ * forwarded on to the promise for the remote promise's next
+ * resolution.
+ */
+ function RemoteHandler(promise, dispatch) {
+ this.promise = promise;
+ this.dispatch = dispatch;
+ }
+ RemoteHandler.prototype = {
+ stateName: 'unresolved remote',
+
+ nearer: function() { return this.promise; }
+ };
+
+ function makeRemote(remoteDispatch, nextSlotP) {
+ var remotePromise;
+
+ function dispatch(OP, args) {
+ if (OP === 'WHEN') {
+ // Send "when"s to the remote promise's eventual next
+ // resolution. This has the effect of buffering them locally
+ // until there is such a next resolution.
+ return Q(nextSlotP).get('value').when(args[0], args[1]);
+ }
+ return remoteDispatch(OP, args);
+ }
+ remotePromise = new Promise(RemoteHandler, remoteDispatch);
+
+
+ Q(nextSlotP).when(function(nextSlot) {
+ become(handle(remotePromise, Q(nextSlot.value)));
+ }, function(reason) {
+ become(handle(remotePromise, reject(reason)));
+ }).end();
+
+ return remotePromise;
+ };
+
+
+ /*************************************************************************
+ * <p>A promise is an object which represents a reference to some
+ * other object, where the other object might be elsewhere (e.g., on
+ * a remote machine) or elsewhen (e.g., not yet computed).
+ *
+ * <p>The Promise constructor must not escape. Clients of this module
+ * use the Q function to make promises from non-promises. Since
+ * Promise.prototype does escape, it must not point back at Promise.
+ *
+ * <p>The various methods on a genuine promise never execute "user
+ * code", i.e., possibly untrusted client code, during the immediate
+ * call to the promise method, protecting the caller from plan
+ * interference hazards. Rather, any such execution happens on later
+ * turns scheduled by the promise method. Except for "end", which
+ * returns nothing, all other promise methods return genuine
+ * promises, enabling safe chaining.
+ */
+ function Promise(HandlerMaker, arg) {
+ var handler = new HandlerMaker(this, arg);
+ handlers.set(this, handler);
+ freeze(this);
+ }
+ function DontMakePromise() {
+ throw new Error('Make promises by calling Q()');
+ }
+ DontMakePromise.prototype = Promise.prototype = {
+ constructor: DontMakePromise,
+
+ toString: function() {
+ return '[' + handle(this).stateName + ' promise]';
+ },
+ post: function(opt_name, args) {
+ var that = this;
+ return postpone(function() {
+ return handle(that).dispatch('POST', [opt_name, args]);
+ });
+ },
+ send: function(opt_name, var_args) {
+ return applyFn(this.post, this, [opt_name, sliceFn(arguments, 1)]);
+ },
+ get: function(name) {
+ var that = this;
+ return postpone(function() {
+ return handle(that).dispatch('GET', [name]);
+ });
+ },
+ put: function(name, value) {
+ var that = this;
+ return postpone(function() {
+ return handle(that).dispatch('PUT', [name, value]);
+ });
+ },
+ 'delete': function(name) {
+ var that = this;
+ return postpone(function() {
+ return handle(that).dispatch('DELETE', [name]);
+ });
+ },
+ when: function(callback, opt_errback) {
+ var errback = opt_errback || function(reason) { throw reason; };
+ var done = false;
+
+ /** success continuation */
+ function sk(value) {
+ if (done) { throw new Error('This "when" already done.'); }
+ done = true;
+ return postpone(function() { return callback(value); });
+ }
+ /** failure continuation */
+ function fk(reason) {
+ if (done) { throw new Error('This "when" already done.'); }
+ done = true;
+ return postpone(function() { return errback(reason); });
+ }
+
+ var that = this;
+ return postpone(function() {
+ return handle(that).dispatch('WHEN', [sk, fk]);
+ });
+ },
+ end: function() {
+ this.when(function(){},
+ function(reason) {
+ // So if this nextTick logs throws that terminate a turn, it
+ // will also log this reason.
+ nextTick(function() { throw reason; });
+ });
+ }
+ };
+ def(DontMakePromise);
+
+ function nearer(target1) {
+ var optHandler = handle(target1);
+ if (!optHandler) { return target1; }
+ return optHandler.nearer();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+
+ Q.reject = reject;
+ Q.defer = defer;
+ Q.isPromise = isPromise;
+
+ Q.makeFar = makeFar;
+
+ Q.makeRemote = makeRemote;
+
+ Q.nearer = nearer;
+
+ theViciousCycle = reject(new Error('vicious promise cycle'));
+ theViciousCycleHandler = handle(theViciousCycle);
+
+ //////////////////////////////////////////////////////////////////////////
+ // Non-fundamental conveniences below.
+
+ Q.delay = function(millis, opt_answer) {
+ var result = Q.defer();
+ setTimeout(function() { result.resolve(opt_answer); }, millis);
+ return result.promise;
+ };
+
+ Q.race = function(var_args) {
+ var answerPs = sliceFn(arguments, 0);
+ var result = Q.defer();
+ answerPs.forEach(function(answerP) {
+ Q(answerP).when(function(answer) {
+ result.resolve(answer);
+ }, function(err) {
+ result.resolve(Q.reject(err));
+ });
+ });
+ return result.promise;
+ };
+
+ Q.all = function(var_args) {
+ var answerPs = sliceFn(arguments, 0);
+ var countDown = answerPs.length;
+ var answers = [];
+ if (countDown === 0) { return Q(answers); }
+ var result = Q.defer();
+ answerPs.forEach(function(answerP, index) {
+ Q(answerP).when(function(answer) {
+ answers[index] = answer;
+ if (--countDown === 0) {
+ // Note: Only a shallow freeze(), not a def().
+ result.resolve(Object.freeze(answers));
+ }
+ }, function(err) {
+ result.resolve(Q.reject(err));
+ });
+ });
+ return result.promise;
+ };
+
+ Q.join = function(var_args) {
+ var args = sliceFn(arguments, 0);
+ var len = args.length;
+ if (len === 0) {
+ return Q.reject(new Error('No references joined'));
+ }
+ return applyFn(Q.all, void 0, args).when(function(fulfilleds) {
+ var first = fulfilleds[0];
+ for (var i = 1; i < len; i++) {
+ if (!is(first, fulfilleds[i])) {
+ throw new Error("not the same");
+ }
+ }
+ // is() guarantees there's no observable difference between
+ // first and any of the others
+ return first;
+ });
+ };
+
+ Q.memoize = function(oneArgFuncP, opt_memoMap) {
+ var memoMap = opt_memoMap || WeakMap();
+
+ function oneArgMemo(arg) {
+ var resultP = memoMap.get(arg);
+ if (!resultP) {
+ resultP = Q(oneArgFuncP).send(void 0, arg);
+ memoMap.set(arg, resultP);
+ }
+ return resultP;
+ }
+ return constFunc(oneArgMemo);
+ };
+
+ /**
+ * On platforms with generators (either ES-Harmony or existing
+ * FF), this can be used with generators to express <a href=
+ * "http://wiki.ecmascript.org/doku.php?id=strawman:async_functions"
+ * >Asynchronous Functions</a>. Please see that page for further
+ * explanation.
+ */
+ Q.async = function(generatorFunc) {
+ function asyncFunc(var_args) {
+ var args = sliceFn(arguments, 0);
+ var generator = generatorFunc.apply(this, args);
+ var callback = continuer.bind(void 0, 'send');
+ var errback = continuer.bind(void 0, 'throw');
+
+ function continuer(verb, valueOrErr) {
+ var promisedValue;
+ try {
+ promisedValue = generator[verb](valueOrErr);
+ } catch (err) {
+ if (isStopIteration(err)) { return Q(err.value); }
+ return Q.reject(err);
+ }
+ return Q(promisedValue).when(callback, errback);
+ }
+
+ return callback(void 0);
+ }
+ return constFunc(asyncFunc);
+ };
+
+ return def(Q);
+ };
+ def(makeQ);
+ ses.makeQ = makeQ;
+ })();
26 node_modules/q/.tmp/map.js
@@ -0,0 +1,26 @@
+
+var Q = require("../q");
+
+Q.resolve([1, 2, 3])
+.map(function (n) {
+ console.log('A', n);
+ return Q.delay(n + 1, 100 * Math.random());
+})
+.map(function (n) {
+ console.log('B', n);
+ return n + 1;
+})
+.map(function (n) {
+ console.log('C', n);
+ return n + 1;
+})
+.map(function (n) {
+ console.log('D', n);
+ return n + 1;
+})
+.all()
+.then(function (all) {
+ console.log('final', all);
+})
+.end()
+
217 node_modules/q/.tmp/markm-mzero.js
@@ -0,0 +1,217 @@
+// Copyright (C) 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * Implementation of
+ * http://wiki.ecmascript.org/doku.php?id=strawman:concurrency
+ *
+ * <p>Assumes ES5-strict. Compatible with base ES5-strict or SES. When
+ * run on SES, has specified security properties.
+ */
+var Q;
+
+(function(){
+ "use strict";
+
+ var def = typeof cajaVM === 'undefined' ? Object.freeze : cajaVM.def;
+ var apply = Function.prototype.apply;
+ var slice = [].slice;
+
+ function handle(target) {
+ var handler = def({
+ resolution: function() { return target; },
+ get: function(name) { return target[name]; },
+ post: function(opt_name, args) {
+ if (opt_name === void 0) {
+ return apply.call(target, void 0, args);
+ }
+ return apply.call(target[opt_name], target, args);
+ },
+ put: function(name, newVal) { target[name] = newVal; },
+ delete: function(name) {
+ if (!delete target[name]) {
+ throw new TypeError('not deleted: ' + name);
+ }
+ }
+ });
+ return handler;
+ }
+
+ function later(thunk) {
+ var defer = Q.defer();
+ setTimeout(function() {
+ try {
+ defer.resolve(thunk());
+ } catch (err) {
+ defer.resolve(Q.reject(err));
+ }
+ }, 0);
+ return defer.promise;
+ }
+
+ /**
+ * An encapsulated map from genuine promises to encapsulated well
+ * behaved trigger functions.
+ *
+ * <p>A trigger is a function from an a well behaved success
+ * continuation and an optional well behaved failure continuation
+ * to a genuine promise. A success continuation is a function from
+ * an untrusted handler to a genuine promise. A failure
+ * continuation is a function from an untrusted error (the reason)
+ * to a genuine promise.
+ *
+ * <p>Well behaved success and failure continuations do not run any
+ * user code during the current turn, protecting the caller from
+ * interleaving. A well behaved trigger given well behaved success
+ * and failure continuations also does not run any user code during
+ * the current turn. For each call to a trigger, a well behaved
+ * trigger will call no more than one of its arguments and call it
+ * nore more than once.
+ *
+ * <p>Invariants: Only genuine promises and well behaved trigger
+ * functions are stored here, and these trigger functions are only
+ * ever called with well behaved success and failure
+ * continuations.
+ */
+ var triggers = WeakMap();
+ function getTrigger(target) {
+ if (target === Object(target)) { return triggers.get(target); }
+ return void 0;
+ }
+
+ function Promise(trigger) {
+ var promise = def({
+ get: function(name) {
+ return trigger(function(handler) {
+ return later(function() { return handler.get(name); });
+ });
+ },
+ post: function(opt_name, args) {
+ return trigger(function(handler) {
+ return later(function() { return handler.post(opt_name, args); });
+ });
+ },
+ send: function(opt_name, var_args) {
+ return promise.post(opt_name, slice.call(arguments, 1));
+ },
+ put: function(name, newVal) {
+ return trigger(function(handler) {
+ return later(function() { return handler.put(name, newVal); });
+ });
+ },
+ delete: function(name) {
+ return trigger(function(handler) {
+ return later(function() { return handler.delete(name); });
+ });
+ },
+ when: function(callback, opt_errback) {
+ return trigger(function(handler) {
+ return later(function() {
+ var r = handler.resolution();
+ if (Q.isPromise(r)) {
+ // Then this can't be the built-in handler. TODO(erights):
+ // Need some way to distinguish whether it should be
+ // treated as a handler for an unresolved remote promise
+ // or a far reference (which is therefore
+ // fulfilled). Until then, treat as an far
+ // reference. TODO(erights): This isn't yet even good
+ // enough for a far reference since it has no way to
+ // spontaneously transition to broken.
+ r = Q.makePromise(handler);
+ }
+ return callback(r);
+ });
+ }, function(reason) {
+ var errback = opt_errback || Q.reject;
+ return later(function() { return errback(reason); });
+ });
+ },
+ end: function() {
+ trigger(function(handler) {}, function(reason) {
+ // log the reason to wherever uncaught exceptions go on
+ // this platform, e.g., onerror(reason).
+ setTimeout(function() { throw reason; }, 0);
+ });
+ return promise;
+ }
+ });
+ triggers.set(promise, trigger);
+ return promise;
+ };
+
+ Q = function Q(target) {
+ if (Q.isPromise(target)) { return target; }
+ return Q.makePromise(handle(target));
+ };
+
+ Q.reject = function(reason) {
+ var rejection = Promise(function(sk, opt_fk) {
+ if (opt_fk) { return opt_fk(reason); }
+ return rejection;
+ });
+ };
+
+ Q.defer = function() {
+ var ks = [];
+
+ var trigger = function(sk, opt_fk) {
+ var fk = opt_fk || Q.reject;
+ var deferred = Q.defer();
+ ks.push({
+ sk: function(handler) { deferred.resolve(sk(handler)); },
+ fk: function(reason) { deferred.resolve(fk)(reason); }
+ });
+ return deferred.promise;
+ };
+
+ var promise = Promise(function(sk, opt_fk) {
+ return trigger(sk, opt_fk);
+ });
+
+ var resolve = function(target) {
+ target = Q(target);
+ trigger = getTrigger(target);
+ triggers.set(promise, trigger); // only a cute optimization
+ resolve = function(target) {}; // throw error?
+
+ ks.forEach(function(k) { trigger(k.sk, k.fk); });
+ ks = void 0; // help gc
+ };
+
+ return def({
+ promise: promise,
+ resolve: function(next) { return resolve(next); }
+ });
+ };
+
+ Q.isPromise = function(target) { return !!getTrigger(target); };
+
+ Q.makePromise = function(handler) {
+ return Promise(function(sk, opt_fk) { return sk(handler); });
+ };
+
+ // Q.near is no longer possible, which is probably ok.
+
+ def(Q);
+})();
+
+function show(print, target) {
+ if (Q.isPromise(target)) {
+ target.when(function(v) { print('ok: ' + v); },
+ function(err) { print('bad: ' + err); });
+ } else {
+ print('now: ' + target);
+ }
+}
+// var sh = show.bind(void 0, console.log.bind(console));
39 node_modules/q/.tmp/promiseAllFulfilled.emaker
@@ -0,0 +1,39 @@
+#!/usr/bin/env rune
+
+pragma.syntax("0.8")
+
+# Copyright 2002 Combex, Inc. under the terms of the MIT X license
+# found at http://www.opensource.org/licenses/mit-license.html ................
+
+/**
+ * Given a list of promises, this returns a promise for the list of
+ * the fulfillment of these promises.
+ * <p>
+ * If all the elements of the list become fulfilled, then the
+ * resolution is this list. If instead any of these promises becomes
+ * broken, then we break our returned promise with this problem. If
+ * one of the promises is or becomes fulfilled and then broken, it may
+ * be counted as either fulfilled or broken.
+ *
+ * @author Mark S. Miller
+ */
+def promiseAllFulfilled0(promises) :any {
+ var countDown := promises.size()
+ if (countDown == 0) { return promises }
+ def [result, resolver] := Ref.promise()
+ for prom in promises {
+ # using Ref.whenResolvedOnly directly because the catch/throw behavior
+ # of the 'when' construct is undesirable. (Thanks to Kevin Reid for
+ # the suggestion)
+ Ref.whenResolvedOnly(prom, def done(_) :void {
+ if (Ref.isBroken(prom)) {
+ resolver.resolve(prom, false)
+ } else if ((countDown -= 1) <= 0) {
+ resolver.resolve(promises)
+ } else {
+ resolver.gettingCloser()
+ }
+ })
+ }
+ return result
+}
93 node_modules/q/.tmp/promiseAllResolved.emaker
@@ -0,0 +1,93 @@
+#!/usr/bin/env rune
+
+# Copyright 2002 Combex, Inc. under the terms of the MIT X license
+# found at http://www.opensource.org/licenses/mit-license.html ................
+
+# NOTE from Kevin Reid: this file was created in 2004. should the above
+# copyright date be changed to that, since it's a semi-new/updated thing, or
+# left as is since the license states "The above copyright notice...shall be
+# included..."?
+
+# Answer from MarkM: IANAL, but as I understand it, if the contents of this
+# file, as an expression of an idea, are largely derived from the original,
+# then the notice should be left alone. But again, IANAL.
+
+pragma.syntax("0.9")
+pragma.enable("explicit-result-guard")
+
+/**
+ * Given a list of promises, this returns a promise for the list of
+ * the resolution of these promises.
+ * <p>
+ * Unlike promiseAllFulfilled, if any of the promises become broken, then
+ * only that entry in the result list is broken.
+ *
+ * @author Mark S. Miller
+ * @author modified by Kevin Reid
+ * @author modified by Mark S. Miller
+ */
+def promiseAllResolved {
+ to run(promises) :any {
+ var countDown := promises.size()
+ if (countDown == 0) { return promises }
+ def [result, resolver] := Ref.promise()
+ for prom in promises {
+ # using Ref.whenResolved directly because the catch/throw behavior
+ # of the 'when' construct is undesirable.
+ Ref.whenResolved(prom, def done(_) :void {
+ if ((countDown -= 1) <= 0) {
+ resolver.resolve(promises)
+ } else {
+ resolver.gettingCloser()
+ }
+ })
+ }
+ return result
+ }
+
+ /**
+ * Return the original list iff all values are resolved, otherwise act as
+ * run/1.
+ */
+ to orNow(refs) :any {
+ for r in refs {
+ if (!Ref.isResolved(r)) {
+ return promiseAllResolved(refs)
+ }
+ }
+ return refs
+ }
+}
+
+ ? pragma.syntax("0.9")
+ ? def promiseAllResolved := <elang:interp.promiseAllResolved>
+ # value: <promiseAllResolved>
+
+ ? def a := promiseAllResolved([1, 2, 3])
+ # value: <Promise>
+
+ ? interp.waitAtTop(a)
+ ? a
+ # value: [1, 2, 3]
+
+ ? def a := promiseAllResolved([def x; x, def y; y, def z; z])
+ # value: <Promise>
+
+ ? bind x := 4
+ # value: 4
+
+ ? a
+ # value: <Promise>
+
+ ? bind y := Ref.broken("boom")
+ # value: <ref broken by problem: boom>
+
+ ? a
+ # value: <Promise>
+
+ ? bind z := [a]
+ # value: [<Promise>]
+
+ ? interp.waitAtTop(timer.whenPast(timer.now() + 100, fn{}))
+ ? a
+ # value: [4, <ref broken by problem: boom>, [<***CYCLE***>]]
159 node_modules/q/.tmp/stream.js
@@ -0,0 +1,159 @@
+var Q = require("../q");
+
+var renewalInterval = 1e10; // a long time
+
+function makeQueue() {
+ var ends = Q.defer();
+ return {
+ "send": function (value) {
+ var next = Q.defer();
+ ends.resolve({
+ "head": value,
+ "tail": next.promise
+ });
+ ends.resolve = next.resolve;
+ },
+ "next": function () {
+ var result = Q.get(ends.promise, "head");
+ ends.promise = Q.get(ends.promise, "tail");
+ return result;
+ }
+ };
+}
+
+function makeStream(label) {
+ var result = Q.defer();
+ var queue = makeQueue();
+
+ var outstanding = 0;
+ var closed;
+
+ function send(value) {
+ outstanding++;
+ if (!closed) {
+ queue.send(value);
+ }
+ // ignore attempts to send values to a
+ // closed stream.
+ }
+
+ function close() {
+ closed = true;
+ // we are not actually closed
+ // until the last value gets emitted
+ }
+
+ function forEach(callback, thisp) {
+ Q.when(queue.next(), function (value) {
+ outstanding--;
+ // summon the next iteration
+ forEach(callback, thisp);
+ // handle this iteration
+ return Q.call(callback, thisp, value)
+ // resolve if this was the last
+ // value out the door.
+ .fin(function () {
+ if (outstanding === 0 && closed) {
+ console.log("CLOSED", label);
+ result.resolve();
+ }
+ });
+ })
+ .end();
+ return result.promise;
+ }
+
+ var promise = Q.makePromise({
+ "forEach": forEach,
+ "all": function () {
+ var object = [];
+ forEach(function (value) {
+ object.push(value);
+ });
+ return Q.when(result.promise, function () {
+ return object;
+ });
+ },
+ "map": function (callback, thisp) {
+ var map = makeStream(label + "|map");
+ forEach(function (value) {
+ Q.call(callback, thisp, value)
+ .then(map.send)
+ .end()
+ })
+ Q.when(result.promise, map.close);
+ return map.promise;
+ },
+ "filter": function (callback, thisp) {
+ var filter = makeStream(label + "|filter");
+ forEach(function (value) {
+ Q.call(callback, thisp, value)
+ .then(function (guard) {
+ if (guard) {
+ filter.send(value);
+ }
+ })
+ .end()
+ })
+ Q.when(result.promise, filter.close);
+ return filter.promise;
+ },
+ "reduce": function (callback, basis, thisp) {
+ var i = 0;
+ forEach(function (value) {
+ basis = Q.when(basis, function (basis) {
+ return Q.call(callback, thisp, basis, value, i++, result.promise);
+ });
+ })
+ return Q.when(result.promise, function () {
+ return basis;
+ });
+ }
+ }, function fallback(op) {
+ var args = Array.prototype.slice.call(arguments);
+ return Q.send.apply(this, [result.promise].concat(args));
+ });
+
+ return {
+ send: send,
+ close: close,
+ promise: promise
+ };
+};
+
+var stream = makeStream("sequence");
+
+stream.promise
+.map(function (n) {
+ console.log("mapping", n);
+ return Q.delay(n, 0)
+ .fin(function () {
+ console.log("emitting", n);
+ })
+})
+.filter(function (n) {
+ console.log("filtering", n);
+ return n % 2;
+})
+.reduce(function (old, n) {
+ console.log('reducing', old, n);
+ return old + n;
+}, 0)
+.then(function (result) {
+ console.log("result", result);
+})
+.end()
+
+var n = 0;
+var handle = setInterval(function () {
+ stream.send(n++);
+ if (n === 10) {
+ console.log("CLOSING");
+ stream.close();
+ }
+}, 10);
+
+Q.when(stream.promise, function () {
+ clearInterval(handle);
+});
+
451 node_modules/q/.tmp/weak-map.js
@@ -0,0 +1,451 @@
+// Copyright (C) 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Install a leaky WeakMap emulation on platforms that
+ * don't provide a built-in one.
+ *
+ * <p>Assumes that an ES5 platform where, if {@code WeakMap} is
+ * already present, then it conforms to the anticipated ES6
+ * specification. To run this file on an ES5 or almost ES5
+ * implementation where the {@code WeakMap} specification does not
+ * quite conform, run <code>repairES5.js</code> first.
+ *
+ * @author Mark S. Miller
+ * @requires ses, crypto, ArrayBuffer, Uint8Array
+ * @overrides WeakMap, WeakMapModule
+ */
+
+/**
+ * This {@code WeakMap} emulation is observably equivalent to the
+ * ES-Harmony WeakMap, but with leakier garbage collection properties.
+ *
+ * <p>As with true WeakMaps, in this emulation, a key does not
+ * retain maps indexed by that key and (crucially) a map does not
+ * retain the keys it indexes. A map by itself also does not retain
+ * the values associated with that map.
+ *
+ * <p>However, the values associated with a key in some map are
+ * retained so long as that key is retained and those associations are
+ * not overridden. For example, when used to support membranes, all
+ * values exported from a given membrane will live for the lifetime
+ * they would have had in the absence of an interposed membrane. Even
+ * when the membrane is revoked, all objects that would have been
+ * reachable in the absence of revocation will still be reachable, as
+ * far as the GC can tell, even though they will no longer be relevant
+ * to ongoing computation.
+ *
+ * <p>The API implemented here is approximately the API as implemented
+ * in FF6.0a1 and agreed to by MarkM, Andreas Gal, and Dave Herman,
+ * rather than the offially approved proposal page. TODO(erights):
+ * upgrade the ecmascript WeakMap proposal page to explain this API
+ * change and present to EcmaScript committee for their approval.
+ *
+ * <p>The first difference between the emulation here and that in
+ * FF6.0a1 is the presence of non enumerable {@code get___, has___,
+ * set___, and delete___} methods on WeakMap instances to represent
+ * what would be the hidden internal properties of a primitive
+ * implementation. Whereas the FF6.0a1 WeakMap.prototype methods
+ * require their {@code this} to be a genuine WeakMap instance (i.e.,
+ * an object of {@code [[Class]]} "WeakMap}), since there is nothing
+ * unforgeable about the pseudo-internal method names used here,
+ * nothing prevents these emulated prototype methods from being
+ * applied to non-WeakMaps with pseudo-internal methods of the same
+ * names.
+ *
+ * <p>Another difference is that our emulated {@code
+ * WeakMap.prototype} is not itself a WeakMap. A problem with the
+ * current FF6.0a1 API is that WeakMap.prototype is itself a WeakMap
+ * providing ambient mutability and an ambient communications
+ * channel. Thus, if a WeakMap is already present and has this
+ * problem, repairES5.js wraps it in a safe wrappper in order to
+ * prevent access to this channel. (See
+ * PATCH_MUTABLE_FROZEN_WEAKMAP_PROTO in repairES5.js).
+ */
+var WeakMap;
+
+/**
+ * If this is a full <a href=
+ * "http://code.google.com/p/es-lab/wiki/SecureableES5"
+ * >secureable ES5</a> platform and the ES-Harmony {@code WeakMap} is
+ * absent, install an approximate emulation.
+ *
+ * <p>If this is almost a secureable ES5 platform, then WeakMap.js
+ * should be run after repairES5.js.
+ *
+ * <p>See {@code WeakMap} for documentation of the garbage collection
+ * properties of this WeakMap emulation.
+ */
+(function WeakMapModule() {
+ "use strict";
+
+ if (typeof ses !== 'undefined' && ses.ok && !ses.ok()) {
+ // already too broken, so give up
+ return;
+ }
+
+ if (typeof WeakMap === 'function') {
+ // assumed fine, so we're done.
+ return;
+ }
+
+ var gopn = Object.getOwnPropertyNames;
+ var defProp = Object.defineProperty;
+
+ /**
+ * Holds the orginal static properties of the Object constructor,
+ * after repairES5 fixes these if necessary to be a more complete
+ * secureable ES5 environment, but before installing the following
+ * WeakMap emulation overrides and before any untrusted code runs.
+ */
+ var originalProps = {};
+ gopn(Object).forEach(function(name) {
+ originalProps[name] = Object[name];
+ });
+
+ /**
+ * Security depends on HIDDEN_NAME being both <i>unguessable</i> and
+ * <i>undiscoverable</i> by untrusted code.
+ *
+ * <p>Given the known weaknesses of Math.random() on existing
+ * browsers, it does not generate unguessability we can be confident
+ * of.
+ *
+ * <p>It is the monkey patching logic in this file that is intended
+ * to ensure undiscoverability. The basic idea is that there are
+ * three fundamental means of discovering properties of an object:
+ * The for/in loop, Object.keys(), and Object.getOwnPropertyNames(),
+ * as well as some proposed ES6 extensions that appear on our
+ * whitelist. The first two only discover enumerable properties, and
+ * we only use HIDDEN_NAME to name a non-enumerable property, so the
+ * only remaining threat should be getOwnPropertyNames and some
+ * proposed ES6 extensions that appear on our whitelist. We monkey
+ * patch them to remove HIDDEN_NAME from the list of properties they
+ * returns.
+ *
+ * <p>TODO(erights): On a platform with built-in Proxies, proxies
+ * could be used to trap and thereby discover the HIDDEN_NAME, so we
+ * need to monkey patch Proxy.create, Proxy.createFunction, etc, in
+ * order to wrap the provided handler with the real handler which
+ * filters out all traps using HIDDEN_NAME.
+ *
+ * <p>TODO(erights): Revisit Mike Stay's suggestion that we use an
+ * encapsulated function at a not-necessarily-secret name, which
+ * uses the Stiegler shared-state rights amplification pattern to
+ * reveal the associated value only to the WeakMap in which this key
+ * is associated with that value. Since only the key retains the
+ * function, the function can also remember the key without causing
+ * leakage of the key, so this doesn't violate our general gc
+ * goals. In addition, because the name need not be a guarded
+ * secret, we could efficiently handle cross-frame frozen keys.
+ */
+ var HIDDEN_NAME = 'ident:' + Math.random() + '___';
+
+ if (typeof crypto !== 'undefined' &&
+ typeof crypto.getRandomValues === 'function' &&
+ typeof ArrayBuffer === 'function' &&
+ typeof Uint8Array === 'function') {
+ var ab = new ArrayBuffer(25);
+ var u8s = new Uint8Array(ab);
+ crypto.getRandomValues(u8s);
+ HIDDEN_NAME = 'rand:' +
+ Array.prototype.map.call(u8s, function(u8) {
+ return (u8 % 36).toString(36);
+ }).join('') + '___';
+ }
+
+ /**
+ * Monkey patch getOwnPropertyNames to avoid revealing the
+ * HIDDEN_NAME.
+ *
+ * <p>The ES5.1 spec requires each name to appear only once, but as
+ * of this writing, this requirement is controversial for ES6, so we
+ * made this code robust against this case. If the resulting extra
+ * search turns out to be expensive, we can probably relax this once
+ * ES6 is adequately supported on all major browsers, iff no browser
+ * versions we support at that time have relaxed this constraint
+ * without providing built-in ES6 WeakMaps.
+ */
+ defProp(Object, 'getOwnPropertyNames', {
+ value: function fakeGetOwnPropertyNames(obj) {
+ return gopn(obj).filter(function(name) {
+ return name !== HIDDEN_NAME;
+ });
+ }
+ });
+
+ /**
+ * getPropertyNames is not in ES5 but it is proposed for ES6 and
+ * does appear in our whitelist, so we need to clean it too.
+ */
+ if ('getPropertyNames' in Object) {
+ defProp(Object, 'getPropertyNames', {
+ value: function fakeGetPropertyNames(obj) {
+ return originalProps.getPropertyNames(obj).filter(function(name) {
+ return name !== HIDDEN_NAME;
+ });
+ }
+ });
+ }
+
+ /**
+ * <p>To treat objects as identity-keys with reasonable efficiency
+ * on ES5 by itself (i.e., without any object-keyed collections), we
+ * need to add a hidden property to such key objects when we
+ * can. This raises several issues:
+ * <ul>
+ * <li>Arranging to add this property to objects before we lose the
+ * chance, and
+ * <li>Hiding the existence of this new property from most
+ * JavaScript code.
+ * <li>Preventing <i>certification theft</i>, where one object is
+ * created falsely claiming to be the key of an associa
+n
+ * actually keyed by another object.
+ * <li>Preventing <i>value theft</i>, where untrusted code with
+ * access to a key object but not a weak map nevertheless
+ * obtains access to the value associated with that key in that
+ * weak map.
+ * </ul>
+ * We do so by
+ * <ul>
+ * <li>Making the name of the hidden property unguessable, so "[]"
+ * indexing, which we cannot intercept, cannot be used to access
+ * a property without knowing the name.
+ * <li>Making the hidden property non-enumerable, so we need not
+ * worry about for-in loops or {@code Object.keys},
+ * <li>monkey patching those reflective methods that would
+ * prevent extensions, to add this hidden property first,
+ * <li>monkey patching those methods that would reveal this
+ * hidden property.
+ * </ul>
+ * Unfortunately, because of same-origin iframes, we cannot reliably
+ * add this hidden property before an object becomes
+ * non-extensible. Instead, if we encounter a non-extensible object
+ * without a hidden record that we can detect (whether or not it has
+ * a hidden record stored under a name secret to us), then we just
+ * use the key object itself to represent its identity in a brute
+ * force leaky map stored in the weak map, losing all the advantages
+ * of weakness for these.
+ */
+ function getHiddenRecord(key) {
+ if (key !== Object(key)) {
+ throw new TypeError('Not an object: ' + key);
+ }
+ var hiddenRecord = key[HIDDEN_NAME];
+ if (hiddenRecord && hiddenRecord.key === key) { return hiddenRecord; }
+ if (!originalProps.isExtensible(key)) {
+ // Weak map must brute force, as explained in doc-comment above.
+ return void 0;
+ }
+ var gets = [];
+ var vals = [];
+ hiddenRecord = {
+ key: key, // self pointer for quick own check above.
+ gets: gets, // get___ methods identifying weak maps
+ vals: vals // values associated with this key in each
+ // corresponding weak map.
+ };
+ defProp(key, HIDDEN_NAME, {
+ value: hiddenRecord,
+ writable: false,
+ enumerable: false,
+ configurable: false
+ });
+ return hiddenRecord;
+ }
+
+
+ /**
+ * Monkey patch operations that would make their argument
+ * non-extensible.
+ *
+ * <p>The monkey patched versions throw a TypeError if their
+ * argument is not an object, so it should only be done to functions
+ * that should throw a TypeError anyway if their argument is not an
+ * object.
+ */
+ (function(){
+ var oldFreeze = Object.freeze;
+ defProp(Object, 'freeze', {
+ value: function identifyingFreeze(obj) {
+ getHiddenRecord(obj);
+ return oldFreeze(obj);
+ }
+ });
+ var oldSeal = Object.seal;
+ defProp(Object, 'seal', {
+ value: function identifyingSeal(obj) {
+ getHiddenRecord(obj);
+ return oldSeal(obj);
+ }
+ });
+ var oldPreventExtensions = Object.preventExtensions;
+ defProp(Object, 'preventExtensions', {
+ value: function identifyingPreventExtensions(obj) {
+ getHiddenRecord(obj);
+ return oldPreventExtensions(obj);
+ }
+ });
+ })();
+
+
+ function constFunc(func) {
+ func.prototype = null;
+ return Object.freeze(func);
+ }
+
+ // Right now (12/25/2012) the histogram supports the current
+ // representation. We should check this occasionally, as a true
+ // constant time representation is easy.
+ // var histogram = [];
+
+ WeakMap = function() {
+ // We are currently (12/25/2012) never encountering any prematurely
+ // non-extensible keys.
+ var keys = []; // brute force for prematurely non-extensible keys.
+ var vals = []; // brute force for corresponding values.
+
+ function get___(key, opt_default) {
+ var hr = getHiddenRecord(key);
+ var i, vs;
+ if (hr) {
+ i = hr.gets.indexOf(get___);
+ vs = hr.vals;
+ } else {
+ i = keys.indexOf(key);
+ vs = vals;
+ }
+ return (i >= 0) ? vs[i] : opt_default;
+ }
+
+ function has___(key) {
+ var hr = getHiddenRecord(key);
+ var i;
+ if (hr) {
+ i = hr.gets.indexOf(get___);
+ } else {
+ i = keys.indexOf(key);
+ }
+ return i >= 0;
+ }
+
+ function set___(key, value) {
+ var hr = getHiddenRecord(key);
+ var i;
+ if (hr) {
+ i = hr.gets.indexOf(get___);
+ if (i >= 0) {
+ hr.vals[i] = value;
+ } else {
+// i = hr.gets.length;
+// histogram[i] = (histogram[i] || 0) + 1;
+ hr.gets.push(get___);
+ hr.vals.push(value);
+ }
+ } else {
+ i = keys.indexOf(key);
+ if (i >= 0) {
+ vals[i] = value;
+ } else {
+ keys.push(key);
+ vals.push(value);
+ }
+ }
+ }
+
+ function delete___(key) {
+ var hr = getHiddenRecord(key);
+ var i;
+ if (hr) {
+ i = hr.gets.indexOf(get___);
+ if (i >= 0) {
+ hr.gets.splice(i, 1);
+ hr.vals.splice(i, 1);
+ }
+ } else {
+ i = keys.indexOf(key);
+ if (i >= 0) {
+ keys.splice(i, 1);
+ vals.splice(i, 1);
+ }
+ }
+ return true;
+ }
+
+ return Object.create(WeakMap.prototype, {
+ get___: { value: constFunc(get___) },
+ has___: { value: constFunc(has___) },
+ set___: { value: constFunc(set___) },
+ delete___: { value: constFunc(delete___) }
+ });
+ };
+ WeakMap.prototype = Object.create(Object.prototype, {
+ get: {
+ /**
+ * Return the value most recently associated with key, or
+ * opt_default if none.
+ */
+ value: function get(key, opt_default) {
+ return this.get___(key, opt_default);
+ },
+ writable: true,
+ configurable: true
+ },
+
+ has: {
+ /**
+ * Is there a value associated with key in this WeakMap?
+ */
+ value: function has(key) {
+ return this.has___(key);
+ },
+ writable: true,
+ configurable: true
+ },
+
+ set: {
+ /**
+ * Associate value with key in this WeakMap, overwriting any
+ * previous association if present.
+ */
+ value: function set(key, value) {
+ this.set___(key, value);
+ },
+ writable: true,
+ configurable: true
+ },
+
+ 'delete': {
+ /**
+ * Remove any association for key in this WeakMap, returning
+ * whether there was one.
+ *
+ * <p>Note that the boolean return here does not work like the
+ * {@code delete} operator. The {@code delete} operator returns
+ * whether the deletion succeeds at bringing about a state in
+ * which the deleted property is absent. The {@code delete}
+ * operator therefore returns true if the property was already
+ * absent, whereas this {@code delete} method returns false if
+ * the association was already absent.
+ */
+ value: function remove(key) {
+ return this.delete___(key);
+ },
+ writable: true,
+ configurable: true
+ }
+ });
+
+})();
80 node_modules/q/package.json
@@ -0,0 +1,80 @@
+{
+ "name": "q",
+ "version": "0.8.6",
+ "description": "A library for promises (CommonJS/Promises/A,B,D)",
+ "homepage": "http://github.com/kriskowal/q/",
+ "author": {
+ "name": "Kris Kowal",
+ "email": "kris@cixar.com",
+ "url": "http://github.com/kriskowal/"
+ },
+ "keywords": [
+ "q",
+ "promise",
+ "deferred",
+ "future",
+ "async",
+ "fluent",
+ "browser",
+ "node"
+ ],
+ "contributors": [
+ {
+ "name": "Kris Kowal",
+ "email": "kris@cixar.com",
+ "url": "http://github.com/kriskowal/"
+ },
+ {
+ "name": "Irakli Gozalishvili",
+ "email": "rfobic@gmail.com",
+ "url": "http://jeditoolkit.com"
+ },
+ {
+ "name": "Domenic Denicola",
+ "email": "domenic@domenicdenicola.com",
+ "url": "http://domenicdenicola.com"
+ }
+ ],
+ "bugs": {
+ "mail": "kris@cixar.com",
+ "url": "http://github.com/kriskowal/q/issues"
+ },
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://github.com/kriskowal/q/raw/master/LICENSE"
+ }
+ ],
+ "main": "q.js",
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/kriskowal/q.git"
+ },
+ "engines": {
+ "node": ">=0.6.0",
+ "teleport": ">=0.2.0"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "jshint": ">=0.7.1",
+ "cover": "*",
+ "jasmine-node": "*"
+ },
+ "scripts": {
+ "test": "jasmine-node spec",
+ "lint": "jshint --show-non-errors q.js",
+ "cover": "cover run node_modules/jasmine-node/bin/jasmine-node spec && cover report html"
+ },
+ "overlay": {
+ "teleport": {
+ "dependencies": {
+ "system": ">=0.0.4"
+ }
+ }
+ },
+ "directories": {
+ "test": "./spec"
+ },
+ "_id": "q@0.8.6",
+ "_from": "Q"
+}
1,502 node_modules/q/q.js
@@ -0,0 +1,1502 @@
+// vim:ts=4:sts=4:sw=4:
+/*jshint browser: true, node: true,
+ curly: true, eqeqeq: true, noarg: true, nonew: true, trailing: true,
+ undef: true */
+/*global define: false, Q: true, msSetImmediate: false, setImmediate: false,
+ ReturnValue: false, cajaVM: false, ses: false */
+/*!
+ *
+ * Copyright 2009-2012 Kris Kowal under the terms of the MIT
+ * license found at http://github.com/kriskowal/q/raw/master/LICENSE
+ *
+ * With parts by Tyler Close
+ * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
+ * at http://www.opensource.org/licenses/mit-license.html
+ * Forked at ref_send.js version: 2009-05-11
+ *
+ * With parts by Mark Miller
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * With formatStackTrace and formatSourcePosition functions
+ * Copyright 2006-2008 the V8 project authors. All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function (definition) {
+ // Turn off strict mode for this function so we can assign to global.Q
+ /*jshint strict: false*/
+
+ // This file will function properly as a <script> tag, or a module
+ // using CommonJS and NodeJS or RequireJS module formats. In
+ // Common/Node/RequireJS, the module exports the Q API and when
+ // executed as a simple <script>, it creates a Q global instead.
+
+ // RequireJS
+ if (typeof define === "function") {
+ define(definition);
+
+ // CommonJS
+ } else if (typeof exports === "object") {
+ definition(void 0, exports);
+
+ // SES (Secure EcmaScript)
+ } else if (typeof ses !== "undefined") {
+ if (!ses.ok()) {
+ return;
+ } else {
+ ses.makeQ = function () {
+ var Q = {};
+ return definition(void 0, Q);
+ };
+ }
+
+ // <script>
+ } else {
+ definition(void 0, Q = {});
+ }
+
+})(function (require, exports) {
+"use strict";
+
+
+// All code after this point will be filtered from stack traces.
+captureLine(new Error());
+
+// shims
+
+// used for fallback "defend" and in "allResolved"
+var noop = function () {};
+
+// for the security conscious, defend may be a deep freeze as provided
+// by cajaVM. Otherwise we try to provide a shallow freeze just to
+// discourage promise changes that are not compatible with secure
+// usage. If Object.freeze does not exist, fall back to doing nothing
+// (no op).
+var defend = Object.freeze || noop;
+if (typeof cajaVM !== "undefined") {
+ defend = cajaVM.def;
+}
+
+// use the fastest possible means to execute a task in a future turn
+// of the event loop.
+var nextTick;
+if (typeof process !== "undefined") {
+ // node
+ nextTick = process.nextTick;
+} else if (typeof msSetImmediate === "function") {
+ // IE 10 only, at the moment
+ // And yes, ``bind``ing to ``window`` is necessary O_o.
+ nextTick = msSetImmediate.bind(window);
+} else if (typeof setImmediate === "function") {
+ // https://github.com/NobleJS/setImmediate
+ nextTick = setImmediate;
+} else if (typeof MessageChannel !== "undefined") {
+ // modern browsers
+ // http://www.nonblocking.io/2011/06/windownexttick.html
+ var channel = new MessageChannel();
+ // linked list of tasks (single, with head node)
+ var head = {}, tail = head;
+ channel.port1.onmessage = function () {
+ head = head.next;
+ var task = head.task;
+ delete head.task;
+ task();
+ };
+ nextTick = function (task) {
+ tail = tail.next = {task: task};
+ channel.port2.postMessage(0);
+ };
+} else {
+ // old browsers
+ nextTick = function (task) {
+ setTimeout(task, 0);
+ };
+}
+
+// Attempt to make generics safe in the face of downstream
+// modifications.
+// There is no situation where this is necessary.
+// If you need a security guarantee, these primordials need to be
+// deeply frozen anyway, and if you don’t need a security guarantee,
+// this is just plain paranoid.
+// However, this does have the nice side-effect of reducing the size
+// of the code by reducing x.call() to merely x(), eliminating many
+// hard-to-minify characters.
+// See Mark Miller’s explanation of what this does.
+// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
+var uncurryThis;
+// I have kept both variations because the first is theoretically
+// faster, if bind is available.
+if (Function.prototype.bind) {
+ var Function_bind = Function.prototype.bind;
+ uncurryThis = Function_bind.bind(Function_bind.call);
+} else {
+ uncurryThis = function (f) {
+ return function (thisp) {
+ return f.call.apply(f, arguments);
+ };
+ };
+}
+
+var array_slice = uncurryThis(Array.prototype.slice);
+
+var array_reduce = uncurryThis(
+ Array.prototype.reduce || function (callback, basis) {
+ var index = 0,
+ length = this.length;
+ // concerning the initial value, if one is not provided
+ if (arguments.length === 1) {
+ // seek to the first value in the array, accounting
+ // for the possibility that is is a sparse array
+ do {
+ if (index in this) {
+ basis = this[index++];
+ break;
+ }
+ if (++index >= length) {
+ throw new TypeError();
+ }
+ } while (1);
+ }
+ // reduce
+ for (; index < length; index++) {
+ // account for the possibility that the array is sparse
+ if (index in this) {
+ basis = callback(basis, this[index], index);
+ }
+ }
+ return basis;
+ }
+);
+
+var array_indexOf = uncurryThis(
+ Array.prototype.indexOf || function (value) {
+ // not a very good shim, but good enough for our one use of it
+ for (var i = 0; i < this.length; i++) {
+ if (this[i] === value) {
+ return i;
+ }
+ }
+ return -1;
+ }
+);
+
+var array_map = uncurryThis(
+ Array.prototype.map || function (callback, thisp) {
+ var self = this;
+ var collect = [];
+ array_reduce(self, function (undefined, value, index) {
+ collect.push(callback.call(thisp, value, index, self));
+ }, void 0);
+ return collect;
+ }
+);
+
+var object_create = Object.create || function (prototype) {
+ function Type() { }
+ Type.prototype = prototype;
+ return new Type();
+};
+
+var object_keys = Object.keys || function (object) {
+ var keys = [];
+ for (var key in object) {
+ keys.push(key);
+ }
+ return keys;
+};
+
+var object_toString = Object.prototype.toString;
+
+// generator related shims
+
+function isStopIteration(exception) {
+ return (
+ object_toString(exception) === "[object StopIteration]" ||
+ exception instanceof QReturnValue
+ );
+}
+
+var QReturnValue;
+if (typeof ReturnValue !== "undefined") {
+ QReturnValue = ReturnValue;
+} else {
+ QReturnValue = function (value) {
+ this.value = value;
+ };
+}
+
+// long stack traces
+
+function formatStackTrace(error, frames) {
+ var lines = [];
+ try {
+ lines.push(error.toString());
+ } catch (e) {
+ try {
+ lines.push("<error: " + e + ">");
+ } catch (ee) {
+ lines.push("<error>");
+ }
+ }
+ for (var i = 0; i < frames.length; i++) {
+ var frame = frames[i];
+ var line;
+
+ // <Inserted by @domenic>
+ if (typeof frame === "string") {
+ lines.push(frame);
+ // </Inserted by @domenic>
+ } else {
+ try {
+ line = formatSourcePosition(frame);
+ } catch (e) {
+ try {
+ line = "<error: " + e + ">";
+ } catch (ee) {
+ // Any code that reaches this point is seriously nasty!
+ line = "<error>";
+ }
+ }
+ lines.push(" at " + line);
+ }
+ }
+ return lines.join("\n");
+}
+
+function formatSourcePosition(frame) {
+ var fileLocation = "";
+ if (frame.isNative()) {
+ fileLocation = "native";
+ } else if (frame.isEval()) {
+ fileLocation = "eval at " + frame.getEvalOrigin();
+ } else {
+ var fileName = frame.getFileName();
+ if (fileName) {
+ fileLocation += fileName;
+ var lineNumber = frame.getLineNumber();
+ if (lineNumber !== null) {
+ fileLocation += ":" + lineNumber;
+ var columnNumber = frame.getColumnNumber();
+ if (columnNumber) {
+ fileLocation += ":" + columnNumber;
+ }
+ }
+ }
+ }
+ if (!fileLocation) {
+ fileLocation = "unknown source";
+ }
+ var line = "";
+ var functionName = frame.getFunction().name;
+ var addPrefix = true;
+ var isConstructor = frame.isConstructor();
+ var isMethodCall = !(frame.isToplevel() || isConstructor);
+ if (isMethodCall) {
+ var methodName = frame.getMethodName();
+ line += frame.getTypeName() + ".";
+ if (functionName) {
+ line += functionName;
+ if (methodName && (methodName !== functionName)) {
+ line += " [as " + methodName + "]";
+ }
+ } else {
+ line += methodName || "<anonymous>";
+ }
+ } else if (isConstructor) {
+ line += "new " + (functionName || "<anonymous>");
+ } else if (functionName) {
+ line += functionName;
+ } else {
+ line += fileLocation;
+ addPrefix = false;
+ }
+ if (addPrefix) {
+ line += " (" + fileLocation + ")";
+ }
+ return line;
+}
+
+function isInternalFrame(fileName, frame) {
+ if (fileName !== qFileName) {
+ return false;
+ }
+ var line = frame.getLineNumber();
+ return line >= qStartingLine && line <= qEndingLine;
+}
+
+/*
+ * Retrieves an array of structured stack frames parsed from the ``stack``
+ * property of a given object.
+ *
+ * @param objectWithStack {Object} an object with a ``stack`` property: usually
+ * an error or promise.
+ *
+ * @returns an array of stack frame objects. For more information, see
+ * [V8's JavaScript stack trace API documentation](http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi).
+ */
+function getStackFrames(objectWithStack) {
+ var oldPrepareStackTrace = Error.prepareStackTrace;
+
+ Error.prepareStackTrace = function (error, frames) {
+ // Filter out frames from the innards of Node and Q.
+ return frames.filter(function (frame) {
+ var fileName = frame.getFileName();
+ return (
+ fileName !== "module.js" &&
+ fileName !== "node.js" &&
+ !isInternalFrame(fileName, frame)
+ );
+ });
+ };
+
+ var stack = objectWithStack.stack;
+
+ Error.prepareStackTrace = oldPrepareStackTrace;
+
+ return stack;
+}
+
+// discover own file name and line number range for filtering stack
+// traces
+var qFileName, qStartingLine, qEndingLine;
+function captureLine(objectWithStack) {
+ if (Error.captureStackTrace) {
+ var fileName, lineNumber;
+
+ var oldPrepareStackTrace = Error.prepareStackTrace;
+
+ Error.prepareStackTrace = function (error, frames) {
+ fileName = frames[0].getFileName();
+ lineNumber = frames[0].getLineNumber();
+ };
+
+ // teases call of temporary prepareStackTrace
+ // JSHint and Closure Compiler generate known warnings here
+ /*jshint expr: true */
+ objectWithStack.stack;
+
+ Error.prepareStackTrace = oldPrepareStackTrace;
+ qFileName = fileName;
+ if (qStartingLine) {
+ qEndingLine = lineNumber;
+ } else {
+ qStartingLine = lineNumber;
+ }
+ }
+}
+
+function deprecate(fn, name, alternative) {
+ return function () {
+ if (typeof console !== "undefined" && typeof console.warn === "function") {
+ console.warn(name + " is deprecated, use " + alternative + " instead.");
+ }
+ return fn.apply(fn, arguments);
+ };
+}
+
+// end of shims
+// beginning of real work
+
+/**
+ * Performs a task in a future turn of the event loop.
+ * @param {Function} task
+ */
+exports.nextTick = nextTick;
+
+/**
+ * Constructs a {promise, resolve} object.
+ *
+ * The resolver is a callback to invoke with a more resolved value for the
+ * promise. To fulfill the promise, invoke the resolver with any value that is
+ * not a function. To reject the promise, invoke the resolver with a rejection
+ * object. To put the promise in the same state as another promise, invoke the
+ * resolver with that other promise.
+ */
+exports.defer = defer;
+function defer() {
+ // if "pending" is an "Array", that indicates that the promise has not yet
+ // been resolved. If it is "undefined", it has been resolved. Each