--- /dev/null
+/** @license MIT License (c) copyright 2013-2014 original author or authors */
+
+/**
+ * Collection of helper functions for wrapping and executing 'traditional'
+ * synchronous functions in a promise interface.
+ *
+ * @author Brian Cavalier
+ * @contributor Renato Zannon
+ */
+
+(function(define) {
+define(function(require) {
+
+ var when = require('./when');
+ var attempt = when['try'];
+ var _liftAll = require('./lib/liftAll');
+ var slice = Array.prototype.slice;
+
+ return {
+ lift: lift,
+ liftAll: liftAll,
+ call: attempt,
+ apply: apply,
+ compose: compose
+ };
+
+ /**
+ * Takes a function and an optional array of arguments (that might be promises),
+ * and calls the function. The return value is a promise whose resolution
+ * depends on the value returned by the function.
+ * @param {function} f function to be called
+ * @param {Array} [args] array of arguments to func
+ * @returns {Promise} promise for the return value of func
+ */
+ function apply(f, args) {
+ return _apply(f, this, args || []);
+ }
+
+ /**
+ * Takes a 'regular' function and returns a version of that function that
+ * returns a promise instead of a plain value, and handles thrown errors by
+ * returning a rejected promise. Also accepts a list of arguments to be
+ * prepended to the new function, as does Function.prototype.bind.
+ *
+ * The resulting function is promise-aware, in the sense that it accepts
+ * promise arguments, and waits for their resolution.
+ * @param {Function} f function to be bound
+ * @param {...*} [args] arguments to be prepended for the new function @deprecated
+ * @returns {Function} a promise-returning function
+ */
+ function lift(f /*, args... */) {
+ var args = arguments.length > 1 ? slice.call(arguments, 1) : [];
+ return function() {
+ return _apply(f, this, args.concat(slice.call(arguments)));
+ };
+ }
+
+ /**
+ * Apply helper that allows specifying thisArg
+ * @private
+ */
+ function _apply(f, thisArg, args) {
+ return args.length === 0
+ ? attempt.call(thisArg, f)
+ : attempt.apply(thisArg, [f].concat(args));
+ }
+
+ /**
+ * Lift all the functions/methods on src
+ * @param {object|function} src source whose functions will be lifted
+ * @param {function?} combine optional function for customizing the lifting
+ * process. It is passed dst, the lifted function, and the property name of
+ * the original function on src.
+ * @param {(object|function)?} dst option destination host onto which to place lifted
+ * functions. If not provided, liftAll returns a new object.
+ * @returns {*} If dst is provided, returns dst with lifted functions as
+ * properties. If dst not provided, returns a new object with lifted functions.
+ */
+ function liftAll(src, combine, dst) {
+ return _liftAll(lift, combine, dst, src);
+ }
+
+ /**
+ * Composes multiple functions by piping their return values. It is
+ * transparent to whether the functions return 'regular' values or promises:
+ * the piped argument is always a resolved value. If one of the functions
+ * throws or returns a rejected promise, the composed promise will be also
+ * rejected.
+ *
+ * The arguments (or promises to arguments) given to the returned function (if
+ * any), are passed directly to the first function on the 'pipeline'.
+ * @param {Function} f the function to which the arguments will be passed
+ * @param {...Function} [funcs] functions that will be composed, in order
+ * @returns {Function} a promise-returning composition of the functions
+ */
+ function compose(f /*, funcs... */) {
+ var funcs = slice.call(arguments, 1);
+
+ return function() {
+ var thisArg = this;
+ var args = slice.call(arguments);
+ var firstPromise = attempt.apply(thisArg, [f].concat(args));
+
+ return when.reduce(funcs, function(arg, func) {
+ return func.call(thisArg, arg);
+ }, firstPromise);
+ };
+ }
+});
+})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
+
+