Commit 9a880be4 authored by Thomas Boyt's avatar Thomas Boyt

Moved from Rake-based builds to Grunt

parent 78e4ef86
/node_modules /node_modules
/promises_tests
/main.js /main.js
/promise-tests/ /tmp
/promises-tests/ /dist
/promises-aplus-tests/
/.bundle
/.jshintrc
/.npmignore
/.bundle
/component.json
/bin
/browser/
/node_modules/ /node_modules/
/Rakefile /tmp
/Gemfile
/Gemfile.lock
/tests/
/promises-aplus-tests
/promises-tests
/promise-tests # for orphans left from earlier versions
/lib
rvm: language: node_js
- 1.9.3 node_js:
bundler_args: --without development - "0.10"
script: "rake test" before_install:
- npm install -g grunt-cli
GEM
remote: https://rubygems.org/
specs:
rake (10.0.2)
PLATFORMS
ruby
DEPENDENCIES
rake
module.exports = function(grunt) {
// Load grunt-microlib config & tasks
var emberConfig = require('grunt-microlib').init.bind(this)(grunt);
grunt.loadNpmTasks('grunt-microlib');
// Custom phantomjs test task
this.registerTask('test:phantom', "Runs tests through the command line using PhantomJS", ['build', 'tests', 'mocha_phantomjs']);
// Custom Node test task
this.registerTask('test:node', ['build', 'tests', 'mochaTest']);
this.registerTask('test', ['build', 'tests', 'mocha_phantomjs', 'mochaTest']);
var config = {
cfg: {
// Name of the project
name: 'rsvp.js',
// Name of the root module (i.e. 'rsvp' -> 'lib/rsvp.js')
barename: 'rsvp',
// Name of the global namespace to export to
namespace: 'RSVP'
},
pkg: grunt.file.readJSON('package.json'),
browserify: {
tests: {
src: ['test/test-adapter.js',
'node_modules/promises-aplus-tests/lib/tests/**/*.js',
'node_modules/promises-aplus-tests/node_modules/sinon/lib/{sinon.js,sinon/*.js}'],
dest: 'tmp/tests-bundle.js'
}
},
mocha_phantomjs: {
phantom: {
options: {
urls: ["test/index.html"],
}
}
},
mochaTest: {
test: {
src: ['test/vendor/assert.js', 'test/test-adapter.js', 'node_modules/promises-aplus-tests/lib/tests/**/*.js', 'tmp/tests.cjs.js'],
options: {
reporter: 'spec'
},
}
}
};
// Merge config into emberConfig, overwriting existing settings
grunt.initConfig(grunt.util._.merge(emberConfig, config));
// Load custom tasks from NPM
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-mocha-phantomjs');
grunt.loadNpmTasks('grunt-mocha-test');
};
...@@ -245,3 +245,13 @@ tom.trigger("poke"); ...@@ -245,3 +245,13 @@ tom.trigger("poke");
The example will work as expected. If you mix `RSVP.EventTarget` into a The example will work as expected. If you mix `RSVP.EventTarget` into a
constructor's prototype, each instance of that constructor will get its constructor's prototype, each instance of that constructor will get its
own callbacks. own callbacks.
## Building & Testing
This package uses the [grunt-microlib](https://github.com/thomasboyt/grunt-microlib) package for building.
Custom tasks:
* `grunt test` - Run Mocha tests through Node and PhantomJS.
* `grunt test:phantom` - Run Mocha tests through PhantomJS (browser build).
* `grunt test:node` - Run Mocha tests through Node (CommonJS build).
require "bundler/setup"
ENV['PATH'] = "#{Dir.pwd}/node_modules/.bin:#{ENV['PATH']}"
directory "browser/rsvp"
directory "node_modules/rsvp"
def module_contents(file)
File.read("lib/#{file}.js")
end
def amd_module(filename)
out_name = filename.sub(/\.js$/, '.amd.js')
output = "browser/#{out_name}"
input = "lib/#{filename}"
file output => ["browser/rsvp", input] do
library = File.read(input)
open output, "w" do |file|
file.puts %x{compile-modules --type amd --anonymous -s < #{input}}
end
end
output
end
def node_module(filename)
if filename == "rsvp.js"
output = "main.js"
else
output = "node_modules/#{filename}"
end
input = "lib/#{filename}"
file output => ["browser", input] do
library = File.read(input)
open output, "w" do |file|
file.puts %x{compile-modules --type cjs --anonymous -s < #{input}}
end
end
output
end
def read(file)
File.read(file)
end
def named_module(name, filename)
name = name.sub(/\.js$/, '')
body = read(filename)
body.sub(/define\(/, "define(#{name.inspect},")
end
# Collect the modules
modules = Dir.chdir "lib" do
Dir["**/*.js"] - ["loader.js"]
end
# Build the AMD modules
amd_modules = modules.reduce({}) do |hash, mod|
hash.merge mod => amd_module(mod)
end
# Build the node modules
node_modules = modules.reduce({}) do |hash, mod|
hash.merge mod => node_module(mod)
end
node_main = "main.js"
# Build a browser build based on the AMD modules
browser_dependencies = ["browser/rsvp"] + amd_modules.values
file "browser/rsvp.js" => browser_dependencies do
output = []
output << %|(function() {|
output << read("lib/loader.js")
amd_modules.each do |name, filename|
output << named_module(name, filename)
end
output << %|window.RSVP = requireModule('rsvp');|
output << %|})();|
open("browser/rsvp.js", "w") do |file|
file.puts output.join("\n")
end
end
# Entry point for node build
file :node => ["node_modules/rsvp"] + node_modules.values
# Minified build
file "browser/rsvp.min.js" => "browser/rsvp.js" do
output = `uglifyjs browser/rsvp.js --mangle`
open "browser/rsvp.min.js", "w" do |file|
file.puts output
end
end
task :install_transpiler do
if `which compile-modules`.empty?
sh "npm install es6-module-transpiler -g"
end
end
task :install_uglify do
if `which uglifyjs`.empty?
sh "npm install uglify-js -g"
end
end
# Build everything
task :dist => [:install_transpiler, :install_uglify, "browser/rsvp.js", "browser/rsvp.min.js", :node]
# Testing
directory "tests/tmp"
test_files = ["tests/test-adapter.js"]
test_files += Dir["promises-tests/lib/tests/**/*.js"]
test_files += Dir["promises-tests/node_modules/sinon/lib/{sinon.js,sinon/*.js}"]
task :install_browserify do
if `which npm`.empty?
puts "You need NPM (for Browserify) to build the browser tests"
exit 1
end
if `which browserify`.empty?
sh "npm install browserify -g"
end
end
file "tests/tmp/test-bundle.js" => [:install_browserify, "tests/tmp"].concat(test_files) do
sh "browserify #{test_files.join(" ")} > tests/tmp/test-bundle.js"
end
task :push => :dist do
sh "git add browser/rsvp.js browser/rsvp.min.js browser/rsvp.amd.js"
sh "git commit -m 'Updates build artifacts'"
end
file "promises-tests" do
sh "git clone https://github.com/promises-aplus/promises-tests"
end
task :update_tests => "promises-tests" do
cd "promises-tests" do
sh "git pull"
sh "npm install"
end
end
desc "Run the tests using Node"
task :test => [:install_transpiler, :update_tests, :node] do
cd "promises-tests" do
sh "node ./lib/cli.js ../tests/test-adapter.js"
end
end
desc "Run the tests using the browser"
task :browser_test => [:update_tests, "tests/tmp/test-bundle.js", :dist] do
sh "open tests/index.html"
end
# Default task is build everything
desc "Build RSVP.js"
task :default => :dist
define(
["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/defer","rsvp/config","rsvp/resolve","rsvp/reject","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) {
"use strict";
var EventTarget = __dependency1__.EventTarget;
var Promise = __dependency2__.Promise;
var denodeify = __dependency3__.denodeify;
var all = __dependency4__.all;
var hash = __dependency5__.hash;
var defer = __dependency6__.defer;
var config = __dependency7__.config;
var resolve = __dependency8__.resolve;
var reject = __dependency9__.reject;
function configure(name, value) {
config[name] = value;
}
__exports__.Promise = Promise;
__exports__.EventTarget = EventTarget;
__exports__.all = all;
__exports__.hash = hash;
__exports__.defer = defer;
__exports__.denodeify = denodeify;
__exports__.configure = configure;
__exports__.resolve = resolve;
__exports__.reject = reject;
});
(function() {
var define, requireModule;
(function() {
var registry = {}, seen = {};
define = function(name, deps, callback) {
registry[name] = { deps: deps, callback: callback };
};
requireModule = function(name) {
if (seen[name]) { return seen[name]; }
seen[name] = {};
var mod = registry[name],
deps = mod.deps,
callback = mod.callback,
reified = [],
exports;
for (var i=0, l=deps.length; i<l; i++) {
if (deps[i] === 'exports') {
reified.push(exports = {});
} else {
reified.push(requireModule(deps[i]));
}
}
var value = callback.apply(this, reified);
return seen[name] = exports || value;
};
})();
define("rsvp/all",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function all(promises) {
if(toString.call(promises) !== "[object Array]") {
throw new TypeError('You must pass an array to all.');
}
return new Promise(function(resolve, reject) {
var results = [], remaining = promises.length,
promise;
if (remaining === 0) {
resolve([]);
}
function resolver(index) {
return function(value) {
resolveAll(index, value);
};
}
function resolveAll(index, value) {
results[index] = value;
if (--remaining === 0) {
resolve(results);
}
}
for (var i = 0; i < promises.length; i++) {
promise = promises[i];
if (promise && typeof promise.then === 'function') {
promise.then(resolver(i), reject);
} else {
resolveAll(i, promise);
}
}
});
}
__exports__.all = all;
});
define("rsvp/async",
["exports"],
function(__exports__) {
"use strict";
var browserGlobal = (typeof window !== 'undefined') ? window : {};
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
var async;
if (typeof process !== 'undefined' &&
{}.toString.call(process) === '[object process]') {
async = function(callback, binding) {
process.nextTick(function() {
callback.call(binding);
});
};
} else if (BrowserMutationObserver) {
var queue = [];
var observer = new BrowserMutationObserver(function() {
var toProcess = queue.slice();
queue = [];
toProcess.forEach(function(tuple) {
var callback = tuple[0], binding = tuple[1];
callback.call(binding);
});
});
var element = document.createElement('div');
observer.observe(element, { attributes: true });
// Chrome Memory Leak: https://bugs.webkit.org/show_bug.cgi?id=93661
window.addEventListener('unload', function(){
observer.disconnect();
observer = null;
});
async = function(callback, binding) {
queue.push([callback, binding]);
element.setAttribute('drainQueue', 'drainQueue');
};
} else {
async = function(callback, binding) {
setTimeout(function() {
callback.call(binding);
}, 1);
};
}
__exports__.async = async;
});
define("rsvp/config",
["rsvp/async","exports"],
function(__dependency1__, __exports__) {
"use strict";
var async = __dependency1__.async;
var config = {};
config.async = async;
__exports__.config = config;
});
define("rsvp/defer",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function defer() {
var deferred = {};
var promise = new Promise(function(resolve, reject) {
deferred.resolve = resolve;
deferred.reject = reject;
});
deferred.promise = promise;
return deferred;
}
__exports__.defer = defer;
});
define("rsvp/events",
["exports"],
function(__exports__) {
"use strict";
var Event = function(type, options) {
this.type = type;
for (var option in options) {
if (!options.hasOwnProperty(option)) { continue; }
this[option] = options[option];
}
};
var indexOf = function(callbacks, callback) {
for (var i=0, l=callbacks.length; i<l; i++) {
if (callbacks[i][0] === callback) { return i; }
}
return -1;
};
var callbacksFor = function(object) {
var callbacks = object._promiseCallbacks;
if (!callbacks) {
callbacks = object._promiseCallbacks = {};
}
return callbacks;
};
var EventTarget = {
mixin: function(object) {
object.on = this.on;
object.off = this.off;
object.trigger = this.trigger;
return object;
},
on: function(eventNames, callback, binding) {
var allCallbacks = callbacksFor(this), callbacks, eventName;
eventNames = eventNames.split(/\s+/);
binding = binding || this;
while (eventName = eventNames.shift()) {
callbacks = allCallbacks[eventName];
if (!callbacks) {
callbacks = allCallbacks[eventName] = [];
}
if (indexOf(callbacks, callback) === -1) {
callbacks.push([callback, binding]);
}
}
},
off: function(eventNames, callback) {
var allCallbacks = callbacksFor(this), callbacks, eventName, index;
eventNames = eventNames.split(/\s+/);
while (eventName = eventNames.shift()) {
if (!callback) {
allCallbacks[eventName] = [];
continue;
}
callbacks = allCallbacks[eventName];
index = indexOf(callbacks, callback);
if (index !== -1) { callbacks.splice(index, 1); }
}
},
trigger: function(eventName, options) {
var allCallbacks = callbacksFor(this),
callbacks, callbackTuple, callback, binding, event;
if (callbacks = allCallbacks[eventName]) {
// Don't cache the callbacks.length since it may grow
for (var i=0; i<callbacks.length; i++) {
callbackTuple = callbacks[i];
callback = callbackTuple[0];
binding = callbackTuple[1];
if (typeof options !== 'object') {
options = { detail: options };
}
event = new Event(eventName, options);
callback.call(binding, event);
}
}
}
};
__exports__.EventTarget = EventTarget;
});
define("rsvp/hash",
["rsvp/defer","exports"],
function(__dependency1__, __exports__) {
"use strict";
var defer = __dependency1__.defer;
function size(object) {
var size = 0;
for (var prop in object) {
size++;
}
return size;
}
function hash(promises) {
var results = {}, deferred = defer(), remaining = size(promises);
if (remaining === 0) {
deferred.resolve({});
}
var resolver = function(prop) {
return function(value) {
resolveAll(prop, value);
};
};
var resolveAll = function(prop, value) {
results[prop] = value;
if (--remaining === 0) {
deferred.resolve(results);
}
};
var rejectAll = function(error) {
deferred.reject(error);
};
for (var prop in promises) {
if (promises[prop] && typeof promises[prop].then === 'function') {
promises[prop].then(resolver(prop), rejectAll);
} else {
resolveAll(prop, promises[prop]);
}
}
return deferred.promise;
}
__exports__.hash = hash;
});
define("rsvp/node",
["rsvp/promise","rsvp/all","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
var all = __dependency2__.all;
function makeNodeCallbackFor(resolve, reject) {
return function (error, value) {
if (error) {
reject(error);
} else if (arguments.length > 2) {
resolve(Array.prototype.slice.call(arguments, 1));
} else {
resolve(value);
}
};
}
function denodeify(nodeFunc) {
return function() {
var nodeArgs = Array.prototype.slice.call(arguments), resolve, reject;
var thisArg = this;
var promise = new Promise(function(nodeResolve, nodeReject) {
resolve = nodeResolve;
reject = nodeReject;
});
all(nodeArgs).then(function(nodeArgs) {
nodeArgs.push(makeNodeCallbackFor(resolve, reject));
try {
nodeFunc.apply(thisArg, nodeArgs);
} catch(e) {
reject(e);
}
});
return promise;
};
}
__exports__.denodeify = denodeify;
});
define("rsvp/promise",
["rsvp/config","rsvp/events","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
var config = __dependency1__.config;
var EventTarget = __dependency2__.EventTarget;
function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x){
return typeof x === "function";
}
var Promise = function(resolver) {
var promise = this,
resolved = false;
if (typeof resolver !== 'function') {
throw new TypeError('You must pass a resolver function as the sole argument to the promise constructor');
}
if (!(promise instanceof Promise)) {
return new Promise(resolver);
}
var resolvePromise = function(value) {
if (resolved) { return; }
resolved = true;
resolve(promise, value);
};
var rejectPromise = function(value) {
if (resolved) { return; }
resolved = true;
reject(promise, value);
};
this.on('promise:resolved', function(event) {
this.trigger('success', { detail: event.detail });
}, this);
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
this.on('error', onerror);
try {
resolver(resolvePromise, rejectPromise);
} catch(e) {
rejectPromise(e);
}
};
function onerror(event) {
if (config.onerror) {
config.onerror(event.detail);
}
}
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
try {
value = callback(event.detail);
succeeded = true;
} catch(e) {
failed = true;
error = e;
}
} else {
value = event.detail;
succeeded = true;
}
if (handleThenable(promise, value)) {
return;
} else if (hasCallback && succeeded) {
resolve(promise, value);
} else if (failed) {
reject(promise, error);
} else if (type === 'resolve') {
resolve(promise, value);
} else if (type === 'reject') {
reject(promise, value);
}
};
Promise.prototype = {
constructor: Promise,
then: function(done, fail) {
this.off('error', onerror);
var thenPromise = new this.constructor(function() {});
if (this.isFulfilled) {
config.async(function() {
invokeCallback('resolve', thenPromise, done, { detail: this.fulfillmentValue });
}, this);
}
if (this.isRejected) {
config.async(function() {
invokeCallback('reject', thenPromise, fail, { detail: this.rejectedReason });
}, this);
}
this.on('promise:resolved', function(event) {
invokeCallback('resolve', thenPromise, done, event);
});
this.on('promise:failed', function(event) {
invokeCallback('reject', thenPromise, fail, event);
});
return thenPromise;
}
};
EventTarget.mixin(Promise.prototype);
function resolve(promise, value) {
if (promise === value) {
fulfill(promise, value);
} else if (!handleThenable(promise, value)) {
fulfill(promise, value);
}
}
function handleThenable(promise, value) {
var then = null;
if (objectOrFunction(value)) {
try {
then = value.then;
} catch(e) {
reject(promise, e);
return true;
}
if (isFunction(then)) {
try {
then.call(value, function(val) {
if (value !== val) {
resolve(promise, val);
} else {
fulfill(promise, val);
}
}, function(val) {
reject(promise, val);
});
} catch (e) {
reject(promise, e);
}
return true;
}
}
return false;
}
function fulfill(promise, value) {
config.async(function() {
promise.trigger('promise:resolved', { detail: value });
promise.isFulfilled = true;
promise.fulfillmentValue = value;
});
}
function reject(promise, value) {
config.async(function() {
promise.trigger('promise:failed', { detail: value });
promise.isRejected = true;
promise.rejectedReason = value;
});
}
__exports__.Promise = Promise;
});
define("rsvp/reject",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function objectOrFunction(x) {
return typeof x === "function" || (typeof x === "object" && x !== null);
}
function reject(reason) {
return new Promise(function (resolve, reject) {
reject(reason);
});
}
__exports__.reject = reject;
});
define("rsvp/resolve",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function objectOrFunction(x) {
return typeof x === "function" || (typeof x === "object" && x !== null);
}
function resolve(thenable) {
if (thenable instanceof Promise) {
return thenable;
}
var promise = new Promise(function(resolve, reject) {
var then;
try {
if ( objectOrFunction(thenable) ) {
then = thenable.then;
if (typeof then === "function") {
then.call(thenable, resolve, reject);
} else {
resolve(thenable);
}
} else {
resolve(thenable);
}
} catch(error) {
reject(error);
}
});
return promise;
}
__exports__.resolve = resolve;
});
define("rsvp",
["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/defer","rsvp/config","rsvp/resolve","rsvp/reject","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) {
"use strict";
var EventTarget = __dependency1__.EventTarget;
var Promise = __dependency2__.Promise;
var denodeify = __dependency3__.denodeify;
var all = __dependency4__.all;
var hash = __dependency5__.hash;
var defer = __dependency6__.defer;
var config = __dependency7__.config;
var resolve = __dependency8__.resolve;
var reject = __dependency9__.reject;
function configure(name, value) {
config[name] = value;
}
__exports__.Promise = Promise;
__exports__.EventTarget = EventTarget;
__exports__.all = all;
__exports__.hash = hash;
__exports__.defer = defer;
__exports__.denodeify = denodeify;
__exports__.configure = configure;
__exports__.resolve = resolve;
__exports__.reject = reject;
});
window.RSVP = requireModule('rsvp');
})();
!function(){var e,r;!function(){var t={},n={};e=function(e,r,n){t[e]={deps:r,callback:n}};r=function(e){if(n[e]){return n[e]}n[e]={};var i=t[e],o=i.deps,s=i.callback,f=[],c;for(var u=0,a=o.length;u<a;u++){if(o[u]==="exports"){f.push(c={})}else{f.push(r(o[u]))}}var l=s.apply(this,f);return n[e]=c||l}}();e("rsvp/all",["rsvp/promise","exports"],function(e,r){"use strict";var t=e.Promise;function n(e){if(toString.call(e)!=="[object Array]"){throw new TypeError("You must pass an array to all.")}return new t(function(r,t){var n=[],i=e.length,o;if(i===0){r([])}function s(e){return function(r){f(e,r)}}function f(e,t){n[e]=t;if(--i===0){r(n)}}for(var c=0;c<e.length;c++){o=e[c];if(o&&typeof o.then==="function"){o.then(s(c),t)}else{f(c,o)}}})}r.all=n});e("rsvp/async",["exports"],function(e){"use strict";var r=typeof window!=="undefined"?window:{};var t=r.MutationObserver||r.WebKitMutationObserver;var n;if(typeof process!=="undefined"&&{}.toString.call(process)==="[object process]"){n=function(e,r){process.nextTick(function(){e.call(r)})}}else if(t){var i=[];var o=new t(function(){var e=i.slice();i=[];e.forEach(function(e){var r=e[0],t=e[1];r.call(t)})});var s=document.createElement("div");o.observe(s,{attributes:true});window.addEventListener("unload",function(){o.disconnect();o=null});n=function(e,r){i.push([e,r]);s.setAttribute("drainQueue","drainQueue")}}else{n=function(e,r){setTimeout(function(){e.call(r)},1)}}e.async=n});e("rsvp/config",["rsvp/async","exports"],function(e,r){"use strict";var t=e.async;var n={};n.async=t;r.config=n});e("rsvp/defer",["rsvp/promise","exports"],function(e,r){"use strict";var t=e.Promise;function n(){var e={};var r=new t(function(r,t){e.resolve=r;e.reject=t});e.promise=r;return e}r.defer=n});e("rsvp/events",["exports"],function(e){"use strict";var r=function(e,r){this.type=e;for(var t in r){if(!r.hasOwnProperty(t)){continue}this[t]=r[t]}};var t=function(e,r){for(var t=0,n=e.length;t<n;t++){if(e[t][0]===r){return t}}return-1};var n=function(e){var r=e._promiseCallbacks;if(!r){r=e._promiseCallbacks={}}return r};var i={mixin:function(e){e.on=this.on;e.off=this.off;e.trigger=this.trigger;return e},on:function(e,r,i){var o=n(this),s,f;e=e.split(/\s+/);i=i||this;while(f=e.shift()){s=o[f];if(!s){s=o[f]=[]}if(t(s,r)===-1){s.push([r,i])}}},off:function(e,r){var i=n(this),o,s,f;e=e.split(/\s+/);while(s=e.shift()){if(!r){i[s]=[];continue}o=i[s];f=t(o,r);if(f!==-1){o.splice(f,1)}}},trigger:function(e,t){var i=n(this),o,s,f,c,u;if(o=i[e]){for(var a=0;a<o.length;a++){s=o[a];f=s[0];c=s[1];if(typeof t!=="object"){t={detail:t}}u=new r(e,t);f.call(c,u)}}}};e.EventTarget=i});e("rsvp/hash",["rsvp/defer","exports"],function(e,r){"use strict";var t=e.defer;function n(e){var r=0;for(var t in e){r++}return r}function i(e){var r={},i=t(),o=n(e);if(o===0){i.resolve({})}var s=function(e){return function(r){f(e,r)}};var f=function(e,t){r[e]=t;if(--o===0){i.resolve(r)}};var c=function(e){i.reject(e)};for(var u in e){if(e[u]&&typeof e[u].then==="function"){e[u].then(s(u),c)}else{f(u,e[u])}}return i.promise}r.hash=i});e("rsvp/node",["rsvp/promise","rsvp/all","exports"],function(e,r,t){"use strict";var n=e.Promise;var i=r.all;function o(e,r){return function(t,n){if(t){r(t)}else if(arguments.length>2){e(Array.prototype.slice.call(arguments,1))}else{e(n)}}}function s(e){return function(){var r=Array.prototype.slice.call(arguments),t,s;var f=this;var c=new n(function(e,r){t=e;s=r});i(r).then(function(r){r.push(o(t,s));try{e.apply(f,r)}catch(n){s(n)}});return c}}t.denodeify=s});e("rsvp/promise",["rsvp/config","rsvp/events","exports"],function(e,r,t){"use strict";var n=e.config;var i=r.EventTarget;function o(e){return s(e)||typeof e==="object"&&e!==null}function s(e){return typeof e==="function"}var f=function(e){var r=this,t=false;if(typeof e!=="function"){throw new TypeError("You must pass a resolver function as the sole argument to the promise constructor")}if(!(r instanceof f)){return new f(e)}var n=function(e){if(t){return}t=true;a(r,e)};var i=function(e){if(t){return}t=true;p(r,e)};this.on("promise:resolved",function(e){this.trigger("success",{detail:e.detail})},this);this.on("promise:failed",function(e){this.trigger("error",{detail:e.detail})},this);this.on("error",c);try{e(n,i)}catch(o){i(o)}};function c(e){if(n.onerror){n.onerror(e.detail)}}var u=function(e,r,t,n){var i=s(t),o,f,c,u;if(i){try{o=t(n.detail);c=true}catch(v){u=true;f=v}}else{o=n.detail;c=true}if(l(r,o)){return}else if(i&&c){a(r,o)}else if(u){p(r,f)}else if(e==="resolve"){a(r,o)}else if(e==="reject"){p(r,o)}};f.prototype={constructor:f,then:function(e,r){this.off("error",c);var t=new this.constructor(function(){});if(this.isFulfilled){n.async(function(){u("resolve",t,e,{detail:this.fulfillmentValue})},this)}if(this.isRejected){n.async(function(){u("reject",t,r,{detail:this.rejectedReason})},this)}this.on("promise:resolved",function(r){u("resolve",t,e,r)});this.on("promise:failed",function(e){u("reject",t,r,e)});return t}};i.mixin(f.prototype);function a(e,r){if(e===r){v(e,r)}else if(!l(e,r)){v(e,r)}}function l(e,r){var t=null;if(o(r)){try{t=r.then}catch(n){p(e,n);return true}if(s(t)){try{t.call(r,function(t){if(r!==t){a(e,t)}else{v(e,t)}},function(r){p(e,r)})}catch(n){p(e,n)}return true}}return false}function v(e,r){n.async(function(){e.trigger("promise:resolved",{detail:r});e.isFulfilled=true;e.fulfillmentValue=r})}function p(e,r){n.async(function(){e.trigger("promise:failed",{detail:r});e.isRejected=true;e.rejectedReason=r})}t.Promise=f});e("rsvp/reject",["rsvp/promise","exports"],function(e,r){"use strict";var t=e.Promise;function n(e){return typeof e==="function"||typeof e==="object"&&e!==null}function i(e){return new t(function(r,t){t(e)})}r.reject=i});e("rsvp/resolve",["rsvp/promise","exports"],function(e,r){"use strict";var t=e.Promise;function n(e){return typeof e==="function"||typeof e==="object"&&e!==null}function i(e){if(e instanceof t){return e}var r=new t(function(r,t){var i;try{if(n(e)){i=e.then;if(typeof i==="function"){i.call(e,r,t)}else{r(e)}}else{r(e)}}catch(o){t(o)}});return r}r.resolve=i});e("rsvp",["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/defer","rsvp/config","rsvp/resolve","rsvp/reject","exports"],function(e,r,t,n,i,o,s,f,c,u){"use strict";var a=e.EventTarget;var l=r.Promise;var v=t.denodeify;var p=n.all;var h=i.hash;var d=o.defer;var y=s.config;var m=f.resolve;var g=c.reject;function w(e,r){y[e]=r}u.Promise=l;u.EventTarget=a;u.all=p;u.hash=h;u.defer=d;u.denodeify=v;u.configure=w;u.resolve=m;u.reject=g});window.RSVP=r("rsvp")}();
define(
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function all(promises) {
if(toString.call(promises) !== "[object Array]") {
throw new TypeError('You must pass an array to all.');
}
return new Promise(function(resolve, reject) {
var results = [], remaining = promises.length,
promise;
if (remaining === 0) {
resolve([]);
}
function resolver(index) {
return function(value) {
resolveAll(index, value);
};
}
function resolveAll(index, value) {
results[index] = value;
if (--remaining === 0) {
resolve(results);
}
}
for (var i = 0; i < promises.length; i++) {
promise = promises[i];
if (promise && typeof promise.then === 'function') {
promise.then(resolver(i), reject);
} else {
resolveAll(i, promise);
}
}
});
}
__exports__.all = all;
});
define(
["exports"],
function(__exports__) {
"use strict";
var browserGlobal = (typeof window !== 'undefined') ? window : {};
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
var async;
if (typeof process !== 'undefined' &&
{}.toString.call(process) === '[object process]') {
async = function(callback, binding) {
process.nextTick(function() {
callback.call(binding);
});
};
} else if (BrowserMutationObserver) {
var queue = [];
var observer = new BrowserMutationObserver(function() {
var toProcess = queue.slice();
queue = [];
toProcess.forEach(function(tuple) {
var callback = tuple[0], binding = tuple[1];
callback.call(binding);
});
});
var element = document.createElement('div');
observer.observe(element, { attributes: true });
// Chrome Memory Leak: https://bugs.webkit.org/show_bug.cgi?id=93661
window.addEventListener('unload', function(){
observer.disconnect();
observer = null;
});
async = function(callback, binding) {
queue.push([callback, binding]);
element.setAttribute('drainQueue', 'drainQueue');
};
} else {
async = function(callback, binding) {
setTimeout(function() {
callback.call(binding);
}, 1);
};
}
__exports__.async = async;
});
define(
["rsvp/async","exports"],
function(__dependency1__, __exports__) {
"use strict";
var async = __dependency1__.async;
var config = {};
config.async = async;
__exports__.config = config;
});
define(
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function defer() {
var deferred = {};
var promise = new Promise(function(resolve, reject) {
deferred.resolve = resolve;
deferred.reject = reject;
});
deferred.promise = promise;
return deferred;
}
__exports__.defer = defer;
});
define(
["exports"],
function(__exports__) {
"use strict";
var Event = function(type, options) {
this.type = type;
for (var option in options) {
if (!options.hasOwnProperty(option)) { continue; }
this[option] = options[option];
}
};
var indexOf = function(callbacks, callback) {
for (var i=0, l=callbacks.length; i<l; i++) {
if (callbacks[i][0] === callback) { return i; }
}
return -1;
};
var callbacksFor = function(object) {
var callbacks = object._promiseCallbacks;
if (!callbacks) {
callbacks = object._promiseCallbacks = {};
}
return callbacks;
};
var EventTarget = {
mixin: function(object) {
object.on = this.on;
object.off = this.off;
object.trigger = this.trigger;
return object;
},
on: function(eventNames, callback, binding) {
var allCallbacks = callbacksFor(this), callbacks, eventName;
eventNames = eventNames.split(/\s+/);
binding = binding || this;
while (eventName = eventNames.shift()) {
callbacks = allCallbacks[eventName];
if (!callbacks) {
callbacks = allCallbacks[eventName] = [];
}
if (indexOf(callbacks, callback) === -1) {
callbacks.push([callback, binding]);
}
}
},
off: function(eventNames, callback) {
var allCallbacks = callbacksFor(this), callbacks, eventName, index;
eventNames = eventNames.split(/\s+/);
while (eventName = eventNames.shift()) {
if (!callback) {
allCallbacks[eventName] = [];
continue;
}
callbacks = allCallbacks[eventName];
index = indexOf(callbacks, callback);
if (index !== -1) { callbacks.splice(index, 1); }
}
},
trigger: function(eventName, options) {
var allCallbacks = callbacksFor(this),
callbacks, callbackTuple, callback, binding, event;
if (callbacks = allCallbacks[eventName]) {
// Don't cache the callbacks.length since it may grow
for (var i=0; i<callbacks.length; i++) {
callbackTuple = callbacks[i];
callback = callbackTuple[0];
binding = callbackTuple[1];
if (typeof options !== 'object') {
options = { detail: options };
}
event = new Event(eventName, options);
callback.call(binding, event);
}
}
}
};
__exports__.EventTarget = EventTarget;
});
define(
["rsvp/defer","exports"],
function(__dependency1__, __exports__) {
"use strict";
var defer = __dependency1__.defer;
function size(object) {
var size = 0;
for (var prop in object) {
size++;
}
return size;
}
function hash(promises) {
var results = {}, deferred = defer(), remaining = size(promises);
if (remaining === 0) {
deferred.resolve({});
}
var resolver = function(prop) {
return function(value) {
resolveAll(prop, value);
};
};
var resolveAll = function(prop, value) {
results[prop] = value;
if (--remaining === 0) {
deferred.resolve(results);
}
};
var rejectAll = function(error) {
deferred.reject(error);
};
for (var prop in promises) {
if (promises[prop] && typeof promises[prop].then === 'function') {
promises[prop].then(resolver(prop), rejectAll);
} else {
resolveAll(prop, promises[prop]);
}
}
return deferred.promise;
}
__exports__.hash = hash;
});
define(
["rsvp/promise","rsvp/all","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
var all = __dependency2__.all;
function makeNodeCallbackFor(resolve, reject) {
return function (error, value) {
if (error) {
reject(error);
} else if (arguments.length > 2) {
resolve(Array.prototype.slice.call(arguments, 1));
} else {
resolve(value);
}
};
}
function denodeify(nodeFunc) {
return function() {
var nodeArgs = Array.prototype.slice.call(arguments), resolve, reject;
var thisArg = this;
var promise = new Promise(function(nodeResolve, nodeReject) {
resolve = nodeResolve;
reject = nodeReject;
});
all(nodeArgs).then(function(nodeArgs) {
nodeArgs.push(makeNodeCallbackFor(resolve, reject));
try {
nodeFunc.apply(thisArg, nodeArgs);
} catch(e) {
reject(e);
}
});
return promise;
};
}
__exports__.denodeify = denodeify;
});
define(
["rsvp/config","rsvp/events","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
var config = __dependency1__.config;
var EventTarget = __dependency2__.EventTarget;
function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x){
return typeof x === "function";
}
var Promise = function(resolver) {
var promise = this,
resolved = false;
if (typeof resolver !== 'function') {
throw new TypeError('You must pass a resolver function as the sole argument to the promise constructor');
}
if (!(promise instanceof Promise)) {
return new Promise(resolver);
}
var resolvePromise = function(value) {
if (resolved) { return; }
resolved = true;
resolve(promise, value);
};
var rejectPromise = function(value) {
if (resolved) { return; }
resolved = true;
reject(promise, value);
};
this.on('promise:resolved', function(event) {
this.trigger('success', { detail: event.detail });
}, this);
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
this.on('error', onerror);
try {
resolver(resolvePromise, rejectPromise);
} catch(e) {
rejectPromise(e);
}
};
function onerror(event) {
if (config.onerror) {
config.onerror(event.detail);
}
}
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
try {
value = callback(event.detail);
succeeded = true;
} catch(e) {
failed = true;
error = e;
}
} else {
value = event.detail;
succeeded = true;
}
if (handleThenable(promise, value)) {
return;
} else if (hasCallback && succeeded) {
resolve(promise, value);
} else if (failed) {
reject(promise, error);
} else if (type === 'resolve') {
resolve(promise, value);
} else if (type === 'reject') {
reject(promise, value);
}
};
Promise.prototype = {
constructor: Promise,
then: function(done, fail) {
this.off('error', onerror);
var thenPromise = new this.constructor(function() {});
if (this.isFulfilled) {
config.async(function() {
invokeCallback('resolve', thenPromise, done, { detail: this.fulfillmentValue });
}, this);
}
if (this.isRejected) {
config.async(function() {
invokeCallback('reject', thenPromise, fail, { detail: this.rejectedReason });
}, this);
}
this.on('promise:resolved', function(event) {
invokeCallback('resolve', thenPromise, done, event);
});
this.on('promise:failed', function(event) {
invokeCallback('reject', thenPromise, fail, event);
});
return thenPromise;
}
};
EventTarget.mixin(Promise.prototype);
function resolve(promise, value) {
if (promise === value) {
fulfill(promise, value);
} else if (!handleThenable(promise, value)) {
fulfill(promise, value);
}
}
function handleThenable(promise, value) {
var then = null;
if (objectOrFunction(value)) {
try {
then = value.then;
} catch(e) {
reject(promise, e);
return true;
}
if (isFunction(then)) {
try {
then.call(value, function(val) {
if (value !== val) {
resolve(promise, val);
} else {
fulfill(promise, val);
}
}, function(val) {
reject(promise, val);
});
} catch (e) {
reject(promise, e);
}
return true;
}
}
return false;
}
function fulfill(promise, value) {
config.async(function() {
promise.trigger('promise:resolved', { detail: value });
promise.isFulfilled = true;
promise.fulfillmentValue = value;
});
}
function reject(promise, value) {
config.async(function() {
promise.trigger('promise:failed', { detail: value });
promise.isRejected = true;
promise.rejectedReason = value;
});
}
__exports__.Promise = Promise;
});
define(
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function objectOrFunction(x) {
return typeof x === "function" || (typeof x === "object" && x !== null);
}
function reject(reason) {
return new Promise(function (resolve, reject) {
reject(reason);
});
}
__exports__.reject = reject;
});
define(
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function objectOrFunction(x) {
return typeof x === "function" || (typeof x === "object" && x !== null);
}
function resolve(thenable) {
if (thenable instanceof Promise) {
return thenable;
}
var promise = new Promise(function(resolve, reject) {
var then;
try {
if ( objectOrFunction(thenable) ) {
then = thenable.then;
if (typeof then === "function") {
then.call(thenable, resolve, reject);
} else {
resolve(thenable);
}
} else {
resolve(thenable);
}
} catch(error) {
reject(error);
}
});
return promise;
}
__exports__.resolve = resolve;
});
var define, requireModule;
(function() {
var registry = {}, seen = {};
define = function(name, deps, callback) {
registry[name] = { deps: deps, callback: callback };
};
requireModule = function(name) {
if (seen[name]) { return seen[name]; }
seen[name] = {};
var mod = registry[name],
deps = mod.deps,
callback = mod.callback,
reified = [],
exports;
for (var i=0, l=deps.length; i<l; i++) {
if (deps[i] === 'exports') {
reified.push(exports = {});
} else {
reified.push(requireModule(deps[i]));
}
}
var value = callback.apply(this, reified);
return seen[name] = exports || value;
};
})();
import { EventTarget } from "rsvp/events"; import { EventTarget } from "./rsvp/events";
import { Promise } from "rsvp/promise"; import { Promise } from "./rsvp/promise";
import { denodeify } from "rsvp/node"; import { denodeify } from "./rsvp/node";
import { all } from "rsvp/all"; import { all } from "./rsvp/all";
import { hash } from "rsvp/hash"; import { hash } from "./rsvp/hash";
import { defer } from "rsvp/defer"; import { defer } from "./rsvp/defer";
import { config } from "rsvp/config"; import { config } from "./rsvp/config";
import { resolve } from "rsvp/resolve"; import { resolve } from "./rsvp/resolve";
import { reject } from "rsvp/reject"; import { reject } from "./rsvp/reject";
function configure(name, value) { function configure(name, value) {
config[name] = value; config[name] = value;
......
import { Promise } from "rsvp/promise"; /* global toString */
import { Promise } from "./promise";
function all(promises) { function all(promises) {
if(toString.call(promises) !== "[object Array]") { if(toString.call(promises) !== "[object Array]") {
......
import { async } from "rsvp/async"; import { async } from "./async";
var config = {}; var config = {};
config.async = async; config.async = async;
......
import { Promise } from "rsvp/promise"; import { Promise } from "./promise";
function defer() { function defer() {
var deferred = {}; var deferred = {};
......
import { defer } from "rsvp/defer"; import { defer } from "./defer";
function size(object) { function size(object) {
var size = 0; var s = 0;
for (var prop in object) { for (var prop in object) {
size++; s++;
} }
return size; return s;
} }
function hash(promises) { function hash(promises) {
......
import { Promise } from "rsvp/promise"; import { Promise } from "./promise";
import { all } from "rsvp/all"; import { all } from "./all";
function makeNodeCallbackFor(resolve, reject) { function makeNodeCallbackFor(resolve, reject) {
return function (error, value) { return function (error, value) {
......
import { config } from "rsvp/config"; import { config } from "./config";
import { EventTarget } from "rsvp/events"; import { EventTarget } from "./events";
function objectOrFunction(x) { function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null); return isFunction(x) || (typeof x === "object" && x !== null);
......
import { Promise } from "rsvp/promise"; import { Promise } from "./promise";
function objectOrFunction(x) { function objectOrFunction(x) {
......
import { Promise } from "rsvp/promise"; import { Promise } from "./promise";
function objectOrFunction(x) { function objectOrFunction(x) {
return typeof x === "function" || (typeof x === "object" && x !== null); return typeof x === "function" || (typeof x === "object" && x !== null);
......
...@@ -2,23 +2,31 @@ ...@@ -2,23 +2,31 @@
"name": "rsvp", "name": "rsvp",
"version": "2.0.0", "version": "2.0.0",
"description": "A lightweight library that provides tools for organizing asynchronous code", "description": "A lightweight library that provides tools for organizing asynchronous code",
"main": "main.js", "main": "dist/commonjs/main.js",
"directories": { "lib": "lib" }, "directories": {
"lib": "lib"
},
"devDependencies": { "devDependencies": {
"jshint": "~0.9", "jshint": "~0.9",
"promise-tests": "2.0.0", "grunt": "~0.4.1",
"uglify-js": "~2.2", "grunt-microlib": "git://github.com/thomasboyt/grunt-microlib.git",
"es6-module-transpiler": "~0.1.2" "promises-aplus-tests": "~1.3.1",
"grunt-browserify": "~1.0.2",
"grunt-mocha-phantomjs": "~0.2.8",
"grunt-mocha-test": "~0.4.0"
}, },
"scripts": { "scripts": {
"test": "promise-tests all ./tests/test-adapter", "test": "grunt test",
"lint": "jshint lib" "lint": "jshint lib",
"prepublish": "grunt build"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/tildeio/rsvp.js.git" "url": "git://github.com/tildeio/rsvp.js.git"
}, },
"bugs": { "url": "https://github.com/tildeio/rsvp.js/issues" }, "bugs": {
"url": "https://github.com/tildeio/rsvp.js/issues"
},
"keywords": [ "keywords": [
"promises", "promises",
"futures", "futures",
......
...@@ -6,14 +6,15 @@ ...@@ -6,14 +6,15 @@
</head> </head>
<body> <body>
<div id="mocha"></div> <div id="mocha"></div>
<script src="../browser/rsvp.js"></script> <script src="../dist/rsvp-2.0.0.js"></script>
<script src="vendor/assert.js"></script> <script src="vendor/assert.js"></script>
<script src="vendor/mocha.js"></script> <script src="vendor/mocha.js"></script>
<script>mocha.setup({ ui: 'bdd', timeout: 200 })</script> <script>mocha.setup({ ui: 'bdd', timeout: 200 })</script>
<script src="tmp/test-bundle.js"></script> <script src="../tmp/tests-bundle.js"></script>
<script src="extension-tests.js"></script> <script src="tests/extension_test.js"></script>
<script> <script>
mocha.run(); if (window.mochaPhantomJS) { mochaPhantomJS.run(); }
else { mocha.run(); }
</script> </script>
</body> </body>
</html> </html>
/*global RSVP*/ /*global RSVP*/
'use strict';
var Promise; var Promise;
if (typeof RSVP !== 'undefined') { if (typeof RSVP !== 'undefined') {
...@@ -9,7 +7,13 @@ if (typeof RSVP !== 'undefined') { ...@@ -9,7 +7,13 @@ if (typeof RSVP !== 'undefined') {
Promise = RSVP.Promise; Promise = RSVP.Promise;
} else { } else {
// Test the Node build // Test the Node build
var Promise = require('../main').Promise; RSVP = require('../dist/commonjs/main');
Promise = require('../dist/commonjs/main').Promise;
assert = require('./vendor/assert');
}
if (typeof window === 'undefined' && typeof global !== 'undefined') {
window = global;
} }
var adapter = {}; var adapter = {};
......
/*global RSVP, describe, specify, it, assert */ /*global describe, specify, it, assert */
describe("RSVP extensions", function() { describe("RSVP extensions", function() {
describe("self fulfillment", function(){ describe("self fulfillment", function(){
it("treats self fulfillment as the recursive base case", function(done){ it("treats self fulfillment as the recursive base case", function(done){
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment