From d9d8d06ff4b4046c215e531a0586bcf98154a106 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 16 Jun 2014 23:11:39 +0200 Subject: [PATCH] js: Release Mopidy.js v0.3.0 --- js/README.md | 2 +- mopidy/http/data/mopidy.js | 2881 ++++++++++++++++++++++---------- mopidy/http/data/mopidy.min.js | 4 +- 3 files changed, 2027 insertions(+), 860 deletions(-) diff --git a/js/README.md b/js/README.md index 966e9b2e..2dcc8412 100644 --- a/js/README.md +++ b/js/README.md @@ -80,7 +80,7 @@ To run other [grunt](http://gruntjs.com/) targets which isn't predefined in Changelog --------- -### 0.3.0 (UNRELEASED) +### 0.3.0 (2014-06-16) - Upgrade to when.js 3, which brings great performance improvements and better debugging facilities. If you maintain a Mopidy client, you should review the diff --git a/mopidy/http/data/mopidy.js b/mopidy/http/data/mopidy.js index cc72e3e6..d035f931 100644 --- a/mopidy/http/data/mopidy.js +++ b/mopidy/http/data/mopidy.js @@ -1,11 +1,11 @@ -/*! Mopidy.js - built 2014-01-04 +/*! Mopidy.js v0.3.0 - built 2014-06-16 * http://www.mopidy.com/ * Copyright (c) 2014 Stein Magnus Jodal and contributors * Licensed under the Apache License, Version 2.0 */ -!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Mopidy=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { + --nFulfill; + results.push(x); + + if(nFulfill === 0) { + resolve(results); + } + } + } + + function handleReject(e) { + if(nReject > 0) { + --nReject; + errors.push(e); + + if(nReject === 0) { + reject(errors); + } + } + } + }); + } + + /** + * Apply f to the value of each promise in a list of promises + * and return a new list containing the results. + * @param {array} promises + * @param {function} f + * @param {function} fallback + * @returns {Promise} + */ + function map(promises, f, fallback) { + return all(arrayMap.call(promises, function(x) { + return toPromise(x).then(f, fallback); + })); + } + + /** + * Return a promise that will always fulfill with an array containing + * the outcome states of all input promises. The returned promise + * will never reject. + * @param {array} promises + * @returns {Promise} + */ + function settle(promises) { + return all(arrayMap.call(promises, function(p) { + p = toPromise(p); + return p.then(inspect, inspect); + + function inspect() { + return p.inspect(); + } + })); + } + + function reduce(promises, f) { + return arguments.length > 2 + ? arrayReduce.call(promises, reducer, arguments[2]) + : arrayReduce.call(promises, reducer); + + function reducer(result, x, i) { + return toPromise(result).then(function(r) { + return toPromise(x).then(function(x) { + return f(r, x, i); + }); + }); + } + } + + function reduceRight(promises, f) { + return arguments.length > 2 + ? arrayReduceRight.call(promises, reducer, arguments[2]) + : arrayReduceRight.call(promises, reducer); + + function reducer(result, x, i) { + return toPromise(result).then(function(r) { + return toPromise(x).then(function(x) { + return f(r, x, i); + }); + }); + } + } + }; + + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); + +},{}],9:[function(_dereq_,module,exports){ +/** @license MIT License (c) copyright 2010-2014 original author or authors */ +/** @author Brian Cavalier */ +/** @author John Hann */ + +(function(define) { 'use strict'; +define(function() { + + return function flow(Promise) { + + var reject = Promise.reject; + var origCatch = Promise.prototype['catch']; + + /** + * Handle the ultimate fulfillment value or rejection reason, and assume + * responsibility for all errors. If an error propagates out of result + * or handleFatalError, it will be rethrown to the host, resulting in a + * loud stack track on most platforms and a crash on some. + * @param {function?} onResult + * @param {function?} onError + * @returns {undefined} + */ + Promise.prototype.done = function(onResult, onError) { + var h = this._handler; + h.when({ resolve: this._maybeFatal, notify: noop, context: this, + receiver: h.receiver, fulfilled: onResult, rejected: onError, + progress: void 0 }); + }; + + /** + * Add Error-type and predicate matching to catch. Examples: + * promise.catch(TypeError, handleTypeError) + * .catch(predicate, handleMatchedErrors) + * .catch(handleRemainingErrors) + * @param onRejected + * @returns {*} + */ + Promise.prototype['catch'] = Promise.prototype.otherwise = function(onRejected) { + if (arguments.length === 1) { + return origCatch.call(this, onRejected); + } else { + if(typeof onRejected !== 'function') { + return this.ensure(rejectInvalidPredicate); + } + + return origCatch.call(this, createCatchFilter(arguments[1], onRejected)); + } + }; + + /** + * Wraps the provided catch handler, so that it will only be called + * if the predicate evaluates truthy + * @param {?function} handler + * @param {function} predicate + * @returns {function} conditional catch handler + */ + function createCatchFilter(handler, predicate) { + return function(e) { + return evaluatePredicate(e, predicate) + ? handler.call(this, e) + : reject(e); + }; + } + + /** + * Ensures that onFulfilledOrRejected will be called regardless of whether + * this promise is fulfilled or rejected. onFulfilledOrRejected WILL NOT + * receive the promises' value or reason. Any returned value will be disregarded. + * onFulfilledOrRejected may throw or return a rejected promise to signal + * an additional error. + * @param {function} handler handler to be called regardless of + * fulfillment or rejection + * @returns {Promise} + */ + Promise.prototype['finally'] = Promise.prototype.ensure = function(handler) { + if(typeof handler !== 'function') { + // Optimization: result will not change, return same promise + return this; + } + + handler = isolate(handler, this); + return this.then(handler, handler); + }; + + /** + * Recover from a failure by returning a defaultValue. If defaultValue + * is a promise, it's fulfillment value will be used. If defaultValue is + * a promise that rejects, the returned promise will reject with the + * same reason. + * @param {*} defaultValue + * @returns {Promise} new promise + */ + Promise.prototype['else'] = Promise.prototype.orElse = function(defaultValue) { + return this.then(void 0, function() { + return defaultValue; + }); + }; + + /** + * Shortcut for .then(function() { return value; }) + * @param {*} value + * @return {Promise} a promise that: + * - is fulfilled if value is not a promise, or + * - if value is a promise, will fulfill with its value, or reject + * with its reason. + */ + Promise.prototype['yield'] = function(value) { + return this.then(function() { + return value; + }); + }; + + /** + * Runs a side effect when this promise fulfills, without changing the + * fulfillment value. + * @param {function} onFulfilledSideEffect + * @returns {Promise} + */ + Promise.prototype.tap = function(onFulfilledSideEffect) { + return this.then(onFulfilledSideEffect)['yield'](this); + }; + + return Promise; + }; + + function rejectInvalidPredicate() { + throw new TypeError('catch predicate must be a function'); + } + + function evaluatePredicate(e, predicate) { + return isError(predicate) ? e instanceof predicate : predicate(e); + } + + function isError(predicate) { + return predicate === Error + || (predicate != null && predicate.prototype instanceof Error); + } + + // prevent argument passing to f and ignore return value + function isolate(f, x) { + return function() { + f.call(this); + return x; + }; + } + + function noop() {} + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); + +},{}],10:[function(_dereq_,module,exports){ +/** @license MIT License (c) copyright 2010-2014 original author or authors */ +/** @author Brian Cavalier */ +/** @author John Hann */ +/** @author Jeff Escalante */ + +(function(define) { 'use strict'; +define(function() { + + return function fold(Promise) { + + Promise.prototype.fold = function(fn, arg) { + var promise = this._beget(); + this._handler.fold(promise._handler, fn, arg); + return promise; + }; + + return Promise; + }; + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); + +},{}],11:[function(_dereq_,module,exports){ +/** @license MIT License (c) copyright 2010-2014 original author or authors */ +/** @author Brian Cavalier */ +/** @author John Hann */ + +(function(define) { 'use strict'; +define(function() { + + return function inspect(Promise) { + + Promise.prototype.inspect = function() { + return this._handler.inspect(); + }; + + return Promise; + }; + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); + +},{}],12:[function(_dereq_,module,exports){ +/** @license MIT License (c) copyright 2010-2014 original author or authors */ +/** @author Brian Cavalier */ +/** @author John Hann */ + +(function(define) { 'use strict'; +define(function() { + + return function generate(Promise) { + + var resolve = Promise.resolve; + + Promise.iterate = iterate; + Promise.unfold = unfold; + + return Promise; + + /** + * Generate a (potentially infinite) stream of promised values: + * x, f(x), f(f(x)), etc. until condition(x) returns true + * @param {function} f function to generate a new x from the previous x + * @param {function} condition function that, given the current x, returns + * truthy when the iterate should stop + * @param {function} handler function to handle the value produced by f + * @param {*|Promise} x starting value, may be a promise + * @return {Promise} the result of the last call to f before + * condition returns true + */ + function iterate(f, condition, handler, x) { + return unfold(function(x) { + return [x, f(x)]; + }, condition, handler, x); + } + + /** + * Generate a (potentially infinite) stream of promised values + * by applying handler(generator(seed)) iteratively until + * condition(seed) returns true. + * @param {function} unspool function that generates a [value, newSeed] + * given a seed. + * @param {function} condition function that, given the current seed, returns + * truthy when the unfold should stop + * @param {function} handler function to handle the value produced by unspool + * @param x {*|Promise} starting value, may be a promise + * @return {Promise} the result of the last value produced by unspool before + * condition returns true + */ + function unfold(unspool, condition, handler, x) { + return resolve(x).then(function(seed) { + return resolve(condition(seed)).then(function(done) { + return done ? seed : resolve(unspool(seed)).spread(next); + }); + }); + + function next(item, newSeed) { + return resolve(handler(item)).then(function() { + return unfold(unspool, condition, handler, newSeed); + }); + } + } + }; + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); + +},{}],13:[function(_dereq_,module,exports){ +/** @license MIT License (c) copyright 2010-2014 original author or authors */ +/** @author Brian Cavalier */ +/** @author John Hann */ + +(function(define) { 'use strict'; +define(function() { + + return function progress(Promise) { + + /** + * Register a progress handler for this promise + * @param {function} onProgress + * @returns {Promise} + */ + Promise.prototype.progress = function(onProgress) { + return this.then(void 0, void 0, onProgress); + }; + + return Promise; + }; + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); + +},{}],14:[function(_dereq_,module,exports){ +/** @license MIT License (c) copyright 2010-2014 original author or authors */ +/** @author Brian Cavalier */ +/** @author John Hann */ + +(function(define) { 'use strict'; +define(function(_dereq_) { + + var timer = _dereq_('../timer'); + var TimeoutError = _dereq_('../TimeoutError'); + + return function timed(Promise) { + /** + * Return a new promise whose fulfillment value is revealed only + * after ms milliseconds + * @param {number} ms milliseconds + * @returns {Promise} + */ + Promise.prototype.delay = function(ms) { + var p = this._beget(); + var h = p._handler; + + this._handler.map(function delay(x) { + timer.set(function() { h.resolve(x); }, ms); + }, h); + + return p; + }; + + /** + * Return a new promise that rejects after ms milliseconds unless + * this promise fulfills earlier, in which case the returned promise + * fulfills with the same value. + * @param {number} ms milliseconds + * @param {Error|*=} reason optional rejection reason to use, defaults + * to an Error if not provided + * @returns {Promise} + */ + Promise.prototype.timeout = function(ms, reason) { + var hasReason = arguments.length > 1; + var p = this._beget(); + var h = p._handler; + + var t = timer.set(onTimeout, ms); + + this._handler.chain(h, + function onFulfill(x) { + timer.clear(t); + this.resolve(x); // this = p._handler + }, + function onReject(x) { + timer.clear(t); + this.reject(x); // this = p._handler + }, + h.notify); + + return p; + + function onTimeout() { + h.reject(hasReason + ? reason : new TimeoutError('timed out after ' + ms + 'ms')); + } + }; + + return Promise; + }; + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(_dereq_); })); + +},{"../TimeoutError":6,"../timer":19}],15:[function(_dereq_,module,exports){ +/** @license MIT License (c) copyright 2010-2014 original author or authors */ +/** @author Brian Cavalier */ +/** @author John Hann */ + +(function(define) { 'use strict'; +define(function(_dereq_) { + + var timer = _dereq_('../timer'); + + return function unhandledRejection(Promise) { + var logError = noop; + var logInfo = noop; + + if(typeof console !== 'undefined') { + logError = typeof console.error !== 'undefined' + ? function (e) { console.error(e); } + : function (e) { console.log(e); }; + + logInfo = typeof console.info !== 'undefined' + ? function (e) { console.info(e); } + : function (e) { console.log(e); }; + } + + Promise.onPotentiallyUnhandledRejection = function(rejection) { + enqueue(report, rejection); + }; + + Promise.onPotentiallyUnhandledRejectionHandled = function(rejection) { + enqueue(unreport, rejection); + }; + + Promise.onFatalRejection = function(rejection) { + enqueue(throwit, rejection.value); + }; + + var tasks = []; + var reported = []; + var running = false; + + function report(r) { + if(!r.handled) { + reported.push(r); + logError('Potentially unhandled rejection [' + r.id + '] ' + formatError(r.value)); + } + } + + function unreport(r) { + var i = reported.indexOf(r); + if(i >= 0) { + reported.splice(i, 1); + logInfo('Handled previous rejection [' + r.id + '] ' + formatObject(r.value)); + } + } + + function enqueue(f, x) { + tasks.push(f, x); + if(!running) { + running = true; + running = timer.set(flush, 0); + } + } + + function flush() { + running = false; + while(tasks.length > 0) { + tasks.shift()(tasks.shift()); + } + } + + return Promise; + }; + + function formatError(e) { + var s = typeof e === 'object' && e.stack ? e.stack : formatObject(e); + return e instanceof Error ? s : s + ' (WARNING: non-Error used)'; + } + + function formatObject(o) { + var s = String(o); + if(s === '[object Object]' && typeof JSON !== 'undefined') { + s = tryStringify(o, s); + } + return s; + } + + function tryStringify(e, defaultValue) { + try { + return JSON.stringify(e); + } catch(e) { + // Ignore. Cannot JSON.stringify e, stick with String(e) + return defaultValue; + } + } + + function throwit(e) { + throw e; + } + + function noop() {} + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(_dereq_); })); + +},{"../timer":19}],16:[function(_dereq_,module,exports){ +/** @license MIT License (c) copyright 2010-2014 original author or authors */ +/** @author Brian Cavalier */ +/** @author John Hann */ + +(function(define) { 'use strict'; +define(function() { + + return function addWith(Promise) { + /** + * Returns a promise whose handlers will be called with `this` set to + * the supplied `thisArg`. Subsequent promises derived from the + * returned promise will also have their handlers called with `thisArg`. + * Calling `with` with undefined or no arguments will return a promise + * whose handlers will again be called in the usual Promises/A+ way (no `this`) + * thus safely undoing any previous `with` in the promise chain. + * + * WARNING: Promises returned from `with`/`withThis` are NOT Promises/A+ + * compliant, specifically violating 2.2.5 (http://promisesaplus.com/#point-41) + * + * @param {object} thisArg `this` value for all handlers attached to + * the returned promise. + * @returns {Promise} + */ + Promise.prototype['with'] = Promise.prototype.withThis + = Promise.prototype._bindContext; + + return Promise; + }; + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); + + +},{}],17:[function(_dereq_,module,exports){ +/** @license MIT License (c) copyright 2010-2014 original author or authors */ +/** @author Brian Cavalier */ +/** @author John Hann */ + +(function(define) { 'use strict'; +define(function() { + + return function makePromise(environment) { + + var tasks = environment.scheduler; + + var objectCreate = Object.create || + function(proto) { + function Child() {} + Child.prototype = proto; + return new Child(); + }; + + /** + * Create a promise whose fate is determined by resolver + * @constructor + * @returns {Promise} promise + * @name Promise + */ + function Promise(resolver, handler) { + this._handler = resolver === Handler ? handler : init(resolver); + } + + /** + * Run the supplied resolver + * @param resolver + * @returns {makePromise.DeferredHandler} + */ + function init(resolver) { + var handler = new DeferredHandler(); + + try { + resolver(promiseResolve, promiseReject, promiseNotify); + } catch (e) { + promiseReject(e); + } + + return handler; + + /** + * Transition from pre-resolution state to post-resolution state, notifying + * all listeners of the ultimate fulfillment or rejection + * @param {*} x resolution value + */ + function promiseResolve (x) { + handler.resolve(x); + } + /** + * Reject this promise with reason, which will be used verbatim + * @param {Error|*} reason rejection reason, strongly suggested + * to be an Error type + */ + function promiseReject (reason) { + handler.reject(reason); + } + + /** + * Issue a progress event, notifying all progress listeners + * @param {*} x progress event payload to pass to all listeners + */ + function promiseNotify (x) { + handler.notify(x); + } + } + + // Creation + + Promise.resolve = resolve; + Promise.reject = reject; + Promise.never = never; + + Promise._defer = defer; + + /** + * Returns a trusted promise. If x is already a trusted promise, it is + * returned, otherwise returns a new trusted Promise which follows x. + * @param {*} x + * @return {Promise} promise + */ + function resolve(x) { + return isPromise(x) ? x + : new Promise(Handler, new AsyncHandler(getHandler(x))); + } + + /** + * Return a reject promise with x as its reason (x is used verbatim) + * @param {*} x + * @returns {Promise} rejected promise + */ + function reject(x) { + return new Promise(Handler, new AsyncHandler(new RejectedHandler(x))); + } + + /** + * Return a promise that remains pending forever + * @returns {Promise} forever-pending promise. + */ + function never() { + return foreverPendingPromise; // Should be frozen + } + + /** + * Creates an internal {promise, resolver} pair + * @private + * @returns {Promise} + */ + function defer() { + return new Promise(Handler, new DeferredHandler()); + } + + // Transformation and flow control + + /** + * Transform this promise's fulfillment value, returning a new Promise + * for the transformed result. If the promise cannot be fulfilled, onRejected + * is called with the reason. onProgress *may* be called with updates toward + * this promise's fulfillment. + * @param {function=} onFulfilled fulfillment handler + * @param {function=} onRejected rejection handler + * @deprecated @param {function=} onProgress progress handler + * @return {Promise} new promise + */ + Promise.prototype.then = function(onFulfilled, onRejected) { + var parent = this._handler; + + if (typeof onFulfilled !== 'function' && parent.join().state() > 0) { + // Short circuit: value will not change, simply share handler + return new Promise(Handler, parent); + } + + var p = this._beget(); + var child = p._handler; + + parent.when({ + resolve: child.resolve, + notify: child.notify, + context: child, + receiver: parent.receiver, + fulfilled: onFulfilled, + rejected: onRejected, + progress: arguments.length > 2 ? arguments[2] : void 0 + }); + + return p; + }; + + /** + * If this promise cannot be fulfilled due to an error, call onRejected to + * handle the error. Shortcut for .then(undefined, onRejected) + * @param {function?} onRejected + * @return {Promise} + */ + Promise.prototype['catch'] = function(onRejected) { + return this.then(void 0, onRejected); + }; + + /** + * Private function to bind a thisArg for this promise's handlers + * @private + * @param {object} thisArg `this` value for all handlers attached to + * the returned promise. + * @returns {Promise} + */ + Promise.prototype._bindContext = function(thisArg) { + return new Promise(Handler, new BoundHandler(this._handler, thisArg)); + }; + + /** + * Creates a new, pending promise of the same type as this promise + * @private + * @returns {Promise} + */ + Promise.prototype._beget = function() { + var parent = this._handler; + var child = new DeferredHandler(parent.receiver, parent.join().context); + return new this.constructor(Handler, child); + }; + + /** + * Check if x is a rejected promise, and if so, delegate to handler._fatal + * @private + * @param {*} x + */ + Promise.prototype._maybeFatal = function(x) { + if(!maybeThenable(x)) { + return; + } + + var handler = getHandler(x); + var context = this._handler.context; + handler.catchError(function() { + this._fatal(context); + }, handler); + }; + + // Array combinators + + Promise.all = all; + Promise.race = race; + + /** + * Return a promise that will fulfill when all promises in the + * input array have fulfilled, or will reject when one of the + * promises rejects. + * @param {array} promises array of promises + * @returns {Promise} promise for array of fulfillment values + */ + function all(promises) { + /*jshint maxcomplexity:8*/ + var resolver = new DeferredHandler(); + var pending = promises.length >>> 0; + var results = new Array(pending); + + var i, h, x, s; + for (i = 0; i < promises.length; ++i) { + x = promises[i]; + + if (x === void 0 && !(i in promises)) { + --pending; + continue; + } + + if (maybeThenable(x)) { + h = isPromise(x) + ? x._handler.join() + : getHandlerUntrusted(x); + + s = h.state(); + if (s === 0) { + resolveOne(resolver, results, h, i); + } else if (s > 0) { + results[i] = h.value; + --pending; + } else { + resolver.become(h); + break; + } + + } else { + results[i] = x; + --pending; + } + } + + if(pending === 0) { + resolver.become(new FulfilledHandler(results)); + } + + return new Promise(Handler, resolver); + function resolveOne(resolver, results, handler, i) { + handler.map(function(x) { + results[i] = x; + if(--pending === 0) { + this.become(new FulfilledHandler(results)); + } + }, resolver); + } + } + + /** + * Fulfill-reject competitive race. Return a promise that will settle + * to the same state as the earliest input promise to settle. + * + * WARNING: The ES6 Promise spec requires that race()ing an empty array + * must return a promise that is pending forever. This implementation + * returns a singleton forever-pending promise, the same singleton that is + * returned by Promise.never(), thus can be checked with === + * + * @param {array} promises array of promises to race + * @returns {Promise} if input is non-empty, a promise that will settle + * to the same outcome as the earliest input promise to settle. if empty + * is empty, returns a promise that will never settle. + */ + function race(promises) { + // Sigh, race([]) is untestable unless we return *something* + // that is recognizable without calling .then() on it. + if(Object(promises) === promises && promises.length === 0) { + return never(); + } + + var h = new DeferredHandler(); + var i, x; + for(i=0; i 0) { + q.shift().run(); + } + + this._running = false; + + q = this._afterQueue; + while(q.length > 0) { + q.shift()(q.shift(), q.shift()); + } + }; + + return Scheduler; + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(_dereq_); })); + +},{"./Queue":5}],19:[function(_dereq_,module,exports){ +/** @license MIT License (c) copyright 2010-2014 original author or authors */ +/** @author Brian Cavalier */ +/** @author John Hann */ + +(function(define) { 'use strict'; +define(function(_dereq_) { + /*global setTimeout,clearTimeout*/ + var cjsRequire, vertx, setTimer, clearTimer; + + cjsRequire = _dereq_; + + try { + vertx = cjsRequire('vertx'); + setTimer = function (f, ms) { return vertx.setTimer(ms, f); }; + clearTimer = vertx.cancelTimer; + } catch (e) { + setTimer = function(f, ms) { return setTimeout(f, ms); }; + clearTimer = function(t) { return clearTimeout(t); }; + } + + return { + set: setTimer, + clear: clearTimer + }; + +}); +}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(_dereq_); })); + +},{}],20:[function(_dereq_,module,exports){ +/** @license MIT License (c) copyright 2010-2014 original author or authors */ /** - * A lightweight CommonJS Promises/A and when() implementation - * when is part of the cujo.js family of libraries (http://cujojs.com/) - * - * Licensed under the MIT License at: - * http://www.opensource.org/licenses/mit-license.php - * + * Promises/A+ and when() implementation + * when is part of the cujoJS family of libraries (http://cujojs.com/) * @author Brian Cavalier * @author John Hann - * @version 2.7.1 + * @version 3.2.3 */ (function(define) { 'use strict'; -define(function (require) { +define(function (_dereq_) { + + var timed = _dereq_('./lib/decorators/timed'); + var array = _dereq_('./lib/decorators/array'); + var flow = _dereq_('./lib/decorators/flow'); + var fold = _dereq_('./lib/decorators/fold'); + var inspect = _dereq_('./lib/decorators/inspect'); + var generate = _dereq_('./lib/decorators/iterate'); + var progress = _dereq_('./lib/decorators/progress'); + var withThis = _dereq_('./lib/decorators/with'); + var unhandledRejection = _dereq_('./lib/decorators/unhandledRejection'); + var TimeoutError = _dereq_('./lib/TimeoutError'); + + var Promise = [array, flow, fold, generate, progress, + inspect, withThis, timed, unhandledRejection] + .reduce(function(Promise, feature) { + return feature(Promise); + }, _dereq_('./lib/Promise')); + + var slice = Array.prototype.slice; // Public API - when.promise = promise; // Create a pending promise - when.resolve = resolve; // Create a resolved promise - when.reject = reject; // Create a rejected promise - when.defer = defer; // Create a {promise, resolver} pair + when.promise = promise; // Create a pending promise + when.resolve = Promise.resolve; // Create a resolved promise + when.reject = Promise.reject; // Create a rejected promise - when.join = join; // Join 2 or more promises + when.lift = lift; // lift a function to return promises + when['try'] = attempt; // call a function and return a promise + when.attempt = attempt; // alias for when.try - when.all = all; // Resolve a list of promises - when.map = map; // Array.map() for promises - when.reduce = reduce; // Array.reduce() for promises - when.settle = settle; // Settle a list of promises + when.iterate = Promise.iterate; // Generate a stream of promises + when.unfold = Promise.unfold; // Generate a stream of promises - when.any = any; // One-winner race - when.some = some; // Multi-winner race + when.join = join; // Join 2 or more promises - when.isPromise = isPromiseLike; // DEPRECATED: use isPromiseLike - when.isPromiseLike = isPromiseLike; // Is something promise-like, aka thenable + when.all = all; // Resolve a list of promises + when.settle = settle; // Settle a list of promises + + when.any = lift(Promise.any); // One-winner race + when.some = lift(Promise.some); // Multi-winner race + + when.map = map; // Array.map() for promises + when.reduce = reduce; // Array.reduce() for promises + when.reduceRight = reduceRight; // Array.reduceRight() for promises + + when.isPromiseLike = isPromiseLike; // Is something promise-like, aka thenable + + when.Promise = Promise; // Promise constructor + when.defer = defer; // Create a {promise, resolve, reject} tuple + + // Error types + + when.TimeoutError = TimeoutError; /** - * Register an observer for a promise or immediate value. + * Get a trusted promise for x, or by transforming x with onFulfilled * - * @param {*} promiseOrValue - * @param {function?} [onFulfilled] callback to be called when promiseOrValue is + * @param {*} x + * @param {function?} onFulfilled callback to be called when x is * successfully fulfilled. If promiseOrValue is an immediate value, callback * will be invoked immediately. - * @param {function?} [onRejected] callback to be called when promiseOrValue is + * @param {function?} onRejected callback to be called when x is * rejected. - * @param {function?} [onProgress] callback to be called when progress updates - * are issued for promiseOrValue. - * @returns {Promise} a new {@link Promise} that will complete with the return + * @deprecated @param {function?} onProgress callback to be called when progress updates + * are issued for x. + * @returns {Promise} a new promise that will fulfill with the return * value of callback or errback or the completion value of promiseOrValue if * callback and/or errback is not supplied. */ - function when(promiseOrValue, onFulfilled, onRejected, onProgress) { - // Get a trusted promise for the input promiseOrValue, and then - // register promise handlers - return cast(promiseOrValue).then(onFulfilled, onRejected, onProgress); + function when(x, onFulfilled, onRejected) { + var p = Promise.resolve(x); + if(arguments.length < 2) { + return p; + } + + return arguments.length > 3 + ? p.then(onFulfilled, onRejected, arguments[3]) + : p.then(onFulfilled, onRejected); } /** @@ -300,443 +2164,63 @@ define(function (require) { * @returns {Promise} promise whose fate is determine by resolver */ function promise(resolver) { - return new Promise(resolver, - monitorApi.PromiseStatus && monitorApi.PromiseStatus()); + return new Promise(resolver); } /** - * Trusted Promise constructor. A Promise created from this constructor is - * a trusted when.js promise. Any other duck-typed promise is considered - * untrusted. - * @constructor - * @returns {Promise} promise whose fate is determine by resolver - * @name Promise + * Lift the supplied function, creating a version of f that returns + * promises, and accepts promises as arguments. + * @param {function} f + * @returns {Function} version of f that returns promises */ - function Promise(resolver, status) { - var self, value, consumers = []; - - self = this; - this._status = status; - this.inspect = inspect; - this._when = _when; - - // Call the provider resolver to seal the promise's fate - try { - resolver(promiseResolve, promiseReject, promiseNotify); - } catch(e) { - promiseReject(e); - } - - /** - * Returns a snapshot of this promise's current status at the instant of call - * @returns {{state:String}} - */ - function inspect() { - return value ? value.inspect() : toPendingState(); - } - - /** - * Private message delivery. Queues and delivers messages to - * the promise's ultimate fulfillment value or rejection reason. - * @private - */ - function _when(resolve, notify, onFulfilled, onRejected, onProgress) { - consumers ? consumers.push(deliver) : enqueue(function() { deliver(value); }); - - function deliver(p) { - p._when(resolve, notify, onFulfilled, onRejected, onProgress); - } - } - - /** - * Transition from pre-resolution state to post-resolution state, notifying - * all listeners of the ultimate fulfillment or rejection - * @param {*} val resolution value - */ - function promiseResolve(val) { - if(!consumers) { - return; - } - - var queue = consumers; - consumers = undef; - - enqueue(function () { - value = coerce(self, val); - if(status) { - updateStatus(value, status); - } - runHandlers(queue, value); - }); - } - - /** - * Reject this promise with the supplied reason, which will be used verbatim. - * @param {*} reason reason for the rejection - */ - function promiseReject(reason) { - promiseResolve(new RejectedPromise(reason)); - } - - /** - * Issue a progress event, notifying all progress listeners - * @param {*} update progress event payload to pass to all listeners - */ - function promiseNotify(update) { - if(consumers) { - var queue = consumers; - enqueue(function () { - runHandlers(queue, new ProgressingPromise(update)); - }); - } - } + function lift(f) { + return function() { + return _apply(f, this, slice.call(arguments)); + }; } - promisePrototype = Promise.prototype; - /** - * Register handlers for this promise. - * @param [onFulfilled] {Function} fulfillment handler - * @param [onRejected] {Function} rejection handler - * @param [onProgress] {Function} progress handler - * @return {Promise} new Promise - */ - promisePrototype.then = function(onFulfilled, onRejected, onProgress) { - var self = this; - - return new Promise(function(resolve, reject, notify) { - self._when(resolve, notify, onFulfilled, onRejected, onProgress); - }, this._status && this._status.observed()); - }; - - /** - * Register a rejection handler. Shortcut for .then(undefined, onRejected) - * @param {function?} onRejected - * @return {Promise} - */ - promisePrototype['catch'] = promisePrototype.otherwise = function(onRejected) { - return this.then(undef, onRejected); - }; - - /** - * Ensures that onFulfilledOrRejected will be called regardless of whether - * this promise is fulfilled or rejected. onFulfilledOrRejected WILL NOT - * receive the promises' value or reason. Any returned value will be disregarded. - * onFulfilledOrRejected may throw or return a rejected promise to signal - * an additional error. - * @param {function} onFulfilledOrRejected handler to be called regardless of - * fulfillment or rejection + * Call f in a future turn, with the supplied args, and return a promise + * for the result. + * @param {function} f * @returns {Promise} */ - promisePrototype['finally'] = promisePrototype.ensure = function(onFulfilledOrRejected) { - return typeof onFulfilledOrRejected === 'function' - ? this.then(injectHandler, injectHandler)['yield'](this) - : this; - - function injectHandler() { - return resolve(onFulfilledOrRejected()); - } - }; - - /** - * Terminate a promise chain by handling the ultimate fulfillment value or - * rejection reason, and assuming responsibility for all errors. if an - * error propagates out of handleResult or handleFatalError, it will be - * rethrown to the host, resulting in a loud stack track on most platforms - * and a crash on some. - * @param {function?} handleResult - * @param {function?} handleError - * @returns {undefined} - */ - promisePrototype.done = function(handleResult, handleError) { - this.then(handleResult, handleError)['catch'](crash); - }; - - /** - * Shortcut for .then(function() { return value; }) - * @param {*} value - * @return {Promise} a promise that: - * - is fulfilled if value is not a promise, or - * - if value is a promise, will fulfill with its value, or reject - * with its reason. - */ - promisePrototype['yield'] = function(value) { - return this.then(function() { - return value; - }); - }; - - /** - * Runs a side effect when this promise fulfills, without changing the - * fulfillment value. - * @param {function} onFulfilledSideEffect - * @returns {Promise} - */ - promisePrototype.tap = function(onFulfilledSideEffect) { - return this.then(onFulfilledSideEffect)['yield'](this); - }; - - /** - * Assumes that this promise will fulfill with an array, and arranges - * for the onFulfilled to be called with the array as its argument list - * i.e. onFulfilled.apply(undefined, array). - * @param {function} onFulfilled function to receive spread arguments - * @return {Promise} - */ - promisePrototype.spread = function(onFulfilled) { - return this.then(function(array) { - // array may contain promises, so resolve its contents. - return all(array, function(array) { - return onFulfilled.apply(undef, array); - }); - }); - }; - - /** - * Shortcut for .then(onFulfilledOrRejected, onFulfilledOrRejected) - * @deprecated - */ - promisePrototype.always = function(onFulfilledOrRejected, onProgress) { - return this.then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress); - }; - - /** - * Casts x to a trusted promise. If x is already a trusted promise, it is - * returned, otherwise a new trusted Promise which follows x is returned. - * @param {*} x - * @returns {Promise} - */ - function cast(x) { - return x instanceof Promise ? x : resolve(x); + function attempt(f /*, args... */) { + /*jshint validthis:true */ + return _apply(f, this, slice.call(arguments, 1)); } /** - * Returns a resolved promise. The returned promise will be - * - fulfilled with promiseOrValue if it is a value, or - * - if promiseOrValue is a promise - * - fulfilled with promiseOrValue's value after it is fulfilled - * - rejected with promiseOrValue's reason after it is rejected - * In contract to cast(x), this always creates a new Promise - * @param {*} value - * @return {Promise} + * try/lift helper that allows specifying thisArg + * @private */ - function resolve(value) { - return promise(function(resolve) { - resolve(value); - }); - } - - /** - * Returns a rejected promise for the supplied promiseOrValue. The returned - * promise will be rejected with: - * - promiseOrValue, if it is a value, or - * - if promiseOrValue is a promise - * - promiseOrValue's value after it is fulfilled - * - promiseOrValue's reason after it is rejected - * @param {*} promiseOrValue the rejected value of the returned {@link Promise} - * @return {Promise} rejected {@link Promise} - */ - function reject(promiseOrValue) { - return when(promiseOrValue, function(e) { - return new RejectedPromise(e); + function _apply(f, thisArg, args) { + return Promise.all(args).then(function(args) { + return f.apply(thisArg, args); }); } /** * Creates a {promise, resolver} pair, either or both of which * may be given out safely to consumers. - * The resolver has resolve, reject, and progress. The promise - * has then plus extended promise API. - * - * @return {{ - * promise: Promise, - * resolve: function:Promise, - * reject: function:Promise, - * notify: function:Promise - * resolver: { - * resolve: function:Promise, - * reject: function:Promise, - * notify: function:Promise - * }}} + * @return {{promise: Promise, resolve: function, reject: function, notify: function}} */ function defer() { - var deferred, pending, resolved; - - // Optimize object shape - deferred = { - promise: undef, resolve: undef, reject: undef, notify: undef, - resolver: { resolve: undef, reject: undef, notify: undef } - }; - - deferred.promise = pending = promise(makeDeferred); - - return deferred; - - function makeDeferred(resolvePending, rejectPending, notifyPending) { - deferred.resolve = deferred.resolver.resolve = function(value) { - if(resolved) { - return resolve(value); - } - resolved = true; - resolvePending(value); - return pending; - }; - - deferred.reject = deferred.resolver.reject = function(reason) { - if(resolved) { - return resolve(new RejectedPromise(reason)); - } - resolved = true; - rejectPending(reason); - return pending; - }; - - deferred.notify = deferred.resolver.notify = function(update) { - notifyPending(update); - return update; - }; - } + return new Deferred(); } - /** - * Run a queue of functions as quickly as possible, passing - * value to each. - */ - function runHandlers(queue, value) { - for (var i = 0; i < queue.length; i++) { - queue[i](value); - } - } + function Deferred() { + var p = Promise._defer(); - /** - * Coerces x to a trusted Promise - * @param {*} x thing to coerce - * @returns {*} Guaranteed to return a trusted Promise. If x - * is trusted, returns x, otherwise, returns a new, trusted, already-resolved - * Promise whose resolution value is: - * * the resolution value of x if it's a foreign promise, or - * * x if it's a value - */ - function coerce(self, x) { - if (x === self) { - return new RejectedPromise(new TypeError()); - } + function resolve(x) { p._handler.resolve(x); } + function reject(x) { p._handler.reject(x); } + function notify(x) { p._handler.notify(x); } - if (x instanceof Promise) { - return x; - } - - try { - var untrustedThen = x === Object(x) && x.then; - - return typeof untrustedThen === 'function' - ? assimilate(untrustedThen, x) - : new FulfilledPromise(x); - } catch(e) { - return new RejectedPromise(e); - } - } - - /** - * Safely assimilates a foreign thenable by wrapping it in a trusted promise - * @param {function} untrustedThen x's then() method - * @param {object|function} x thenable - * @returns {Promise} - */ - function assimilate(untrustedThen, x) { - return promise(function (resolve, reject) { - fcall(untrustedThen, x, resolve, reject); - }); - } - - makePromisePrototype = Object.create || - function(o) { - function PromisePrototype() {} - PromisePrototype.prototype = o; - return new PromisePrototype(); - }; - - /** - * Creates a fulfilled, local promise as a proxy for a value - * NOTE: must never be exposed - * @private - * @param {*} value fulfillment value - * @returns {Promise} - */ - function FulfilledPromise(value) { - this.value = value; - } - - FulfilledPromise.prototype = makePromisePrototype(promisePrototype); - - FulfilledPromise.prototype.inspect = function() { - return toFulfilledState(this.value); - }; - - FulfilledPromise.prototype._when = function(resolve, _, onFulfilled) { - try { - resolve(typeof onFulfilled === 'function' ? onFulfilled(this.value) : this.value); - } catch(e) { - resolve(new RejectedPromise(e)); - } - }; - - /** - * Creates a rejected, local promise as a proxy for a value - * NOTE: must never be exposed - * @private - * @param {*} reason rejection reason - * @returns {Promise} - */ - function RejectedPromise(reason) { - this.value = reason; - } - - RejectedPromise.prototype = makePromisePrototype(promisePrototype); - - RejectedPromise.prototype.inspect = function() { - return toRejectedState(this.value); - }; - - RejectedPromise.prototype._when = function(resolve, _, __, onRejected) { - try { - resolve(typeof onRejected === 'function' ? onRejected(this.value) : this); - } catch(e) { - resolve(new RejectedPromise(e)); - } - }; - - /** - * Create a progress promise with the supplied update. - * @private - * @param {*} value progress update value - * @return {Promise} progress promise - */ - function ProgressingPromise(value) { - this.value = value; - } - - ProgressingPromise.prototype = makePromisePrototype(promisePrototype); - - ProgressingPromise.prototype._when = function(_, notify, f, r, u) { - try { - notify(typeof u === 'function' ? u(this.value) : this.value); - } catch(e) { - notify(e); - } - }; - - /** - * Update a PromiseStatus monitor object with the outcome - * of the supplied value promise. - * @param {Promise} value - * @param {PromiseStatus} status - */ - function updateStatus(value, status) { - value.then(statusFulfilled, statusRejected); - - function statusFulfilled() { status.fulfilled(); } - function statusRejected(r) { status.rejected(r); } + this.promise = p; + this.resolve = resolve; + this.reject = reject; + this.notify = notify; + this.resolver = { resolve: resolve, reject: reject, notify: notify }; } /** @@ -752,196 +2236,48 @@ define(function (require) { } /** - * Initiates a competitive race, returning a promise that will resolve when - * howMany of the supplied promisesOrValues have resolved, or will reject when - * it becomes impossible for howMany to resolve, for example, when - * (promisesOrValues.length - howMany) + 1 input promises reject. - * - * @param {Array} promisesOrValues array of anything, may contain a mix - * of promises and values - * @param howMany {number} number of promisesOrValues to resolve - * @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then() - * @param {function?} [onRejected] DEPRECATED, use returnedPromise.then() - * @param {function?} [onProgress] DEPRECATED, use returnedPromise.then() - * @returns {Promise} promise that will resolve to an array of howMany values that - * resolved first, or will reject with an array of - * (promisesOrValues.length - howMany) + 1 rejection reasons. - */ - function some(promisesOrValues, howMany, onFulfilled, onRejected, onProgress) { - - return when(promisesOrValues, function(promisesOrValues) { - - return promise(resolveSome).then(onFulfilled, onRejected, onProgress); - - function resolveSome(resolve, reject, notify) { - var toResolve, toReject, values, reasons, fulfillOne, rejectOne, len, i; - - len = promisesOrValues.length >>> 0; - - toResolve = Math.max(0, Math.min(howMany, len)); - values = []; - - toReject = (len - toResolve) + 1; - reasons = []; - - // No items in the input, resolve immediately - if (!toResolve) { - resolve(values); - - } else { - rejectOne = function(reason) { - reasons.push(reason); - if(!--toReject) { - fulfillOne = rejectOne = identity; - reject(reasons); - } - }; - - fulfillOne = function(val) { - // This orders the values based on promise resolution order - values.push(val); - if (!--toResolve) { - fulfillOne = rejectOne = identity; - resolve(values); - } - }; - - for(i = 0; i < len; ++i) { - if(i in promisesOrValues) { - when(promisesOrValues[i], fulfiller, rejecter, notify); - } - } - } - - function rejecter(reason) { - rejectOne(reason); - } - - function fulfiller(val) { - fulfillOne(val); - } - } - }); - } - - /** - * Initiates a competitive race, returning a promise that will resolve when - * any one of the supplied promisesOrValues has resolved or will reject when - * *all* promisesOrValues have rejected. - * - * @param {Array|Promise} promisesOrValues array of anything, may contain a mix - * of {@link Promise}s and values - * @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then() - * @param {function?} [onRejected] DEPRECATED, use returnedPromise.then() - * @param {function?} [onProgress] DEPRECATED, use returnedPromise.then() - * @returns {Promise} promise that will resolve to the value that resolved first, or - * will reject with an array of all rejected inputs. - */ - function any(promisesOrValues, onFulfilled, onRejected, onProgress) { - - function unwrapSingleResult(val) { - return onFulfilled ? onFulfilled(val[0]) : val[0]; - } - - return some(promisesOrValues, 1, unwrapSingleResult, onRejected, onProgress); - } - - /** - * Return a promise that will resolve only once all the supplied promisesOrValues + * Return a promise that will resolve only once all the supplied arguments * have resolved. The resolution value of the returned promise will be an array - * containing the resolution values of each of the promisesOrValues. - * @memberOf when - * - * @param {Array|Promise} promisesOrValues array of anything, may contain a mix - * of {@link Promise}s and values - * @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then() - * @param {function?} [onRejected] DEPRECATED, use returnedPromise.then() - * @param {function?} [onProgress] DEPRECATED, use returnedPromise.then() + * containing the resolution values of each of the arguments. + * @param {...*} arguments may be a mix of promises and values * @returns {Promise} */ - function all(promisesOrValues, onFulfilled, onRejected, onProgress) { - return _map(promisesOrValues, identity).then(onFulfilled, onRejected, onProgress); - } - - /** - * Joins multiple promises into a single returned promise. - * @return {Promise} a promise that will fulfill when *all* the input promises - * have fulfilled, or will reject when *any one* of the input promises rejects. - */ function join(/* ...promises */) { - return _map(arguments, identity); + return Promise.all(arguments); } /** - * Settles all input promises such that they are guaranteed not to - * be pending once the returned promise fulfills. The returned promise - * will always fulfill, except in the case where `array` is a promise - * that rejects. - * @param {Array|Promise} array or promise for array of promises to settle - * @returns {Promise} promise that always fulfills with an array of - * outcome snapshots for each input promise. + * Return a promise that will fulfill once all input promises have + * fulfilled, or reject when any one input promise rejects. + * @param {array|Promise} promises array (or promise for an array) of promises + * @returns {Promise} */ - function settle(array) { - return _map(array, toFulfilledState, toRejectedState); + function all(promises) { + return when(promises, Promise.all); + } + + /** + * Return a promise that will always fulfill with an array containing + * the outcome states of all input promises. The returned promise + * will only reject if `promises` itself is a rejected promise. + * @param {array|Promise} promises array (or promise for an array) of promises + * @returns {Promise} + */ + function settle(promises) { + return when(promises, Promise.settle); } /** * Promise-aware array map function, similar to `Array.prototype.map()`, * but input array may contain promises or values. - * @param {Array|Promise} array array of anything, may contain promises and values + * @param {Array|Promise} promises array of anything, may contain promises and values * @param {function} mapFunc map function which may return a promise or value * @returns {Promise} promise that will fulfill with an array of mapped values * or reject if any input promise rejects. */ - function map(array, mapFunc) { - return _map(array, mapFunc); - } - - /** - * Internal map that allows a fallback to handle rejections - * @param {Array|Promise} array array of anything, may contain promises and values - * @param {function} mapFunc map function which may return a promise or value - * @param {function?} fallback function to handle rejected promises - * @returns {Promise} promise that will fulfill with an array of mapped values - * or reject if any input promise rejects. - */ - function _map(array, mapFunc, fallback) { - return when(array, function(array) { - - return new Promise(resolveMap); - - function resolveMap(resolve, reject, notify) { - var results, len, toResolve, i; - - // Since we know the resulting length, we can preallocate the results - // array to avoid array expansions. - toResolve = len = array.length >>> 0; - results = []; - - if(!toResolve) { - resolve(results); - return; - } - - // Since mapFunc may be async, get all invocations of it into flight - for(i = 0; i < len; i++) { - if(i in array) { - resolveOne(array[i], i); - } else { - --toResolve; - } - } - - function resolveOne(item, i) { - when(item, mapFunc, fallback).then(function(mapped) { - results[i] = mapped; - - if(!--toResolve) { - resolve(results); - } - }, reject, notify); - } - } + function map(promises, mapFunc) { + return when(promises, function(promises) { + return Promise.map(promises, mapFunc); }); } @@ -951,227 +2287,50 @@ define(function (require) { * may return either a value or a promise, *and* initialValue may * be a promise for the starting value. * - * @param {Array|Promise} promise array or promise for an array of anything, + * @param {Array|Promise} promises array or promise for an array of anything, * may contain a mix of promises and values. - * @param {function} reduceFunc reduce function reduce(currentValue, nextValue, index, total), - * where total is the total number of items being reduced, and will be the same - * in each call to reduceFunc. + * @param {function} f reduce function reduce(currentValue, nextValue, index) * @returns {Promise} that will resolve to the final reduced value */ - function reduce(promise, reduceFunc /*, initialValue */) { - var args = fcall(slice, arguments, 1); - - return when(promise, function(array) { - var total; - - total = array.length; - - // Wrap the supplied reduceFunc with one that handles promises and then - // delegates to the supplied. - args[0] = function (current, val, i) { - return when(current, function (c) { - return when(val, function (value) { - return reduceFunc(c, value, i, total); - }); - }); - }; - - return reduceArray.apply(array, args); + function reduce(promises, f /*, initialValue */) { + /*jshint unused:false*/ + var args = slice.call(arguments, 1); + return when(promises, function(array) { + args.unshift(array); + return Promise.reduce.apply(Promise, args); }); } - // Snapshot states - /** - * Creates a fulfilled state snapshot - * @private - * @param {*} x any value - * @returns {{state:'fulfilled',value:*}} + * Traditional reduce function, similar to `Array.prototype.reduceRight()`, but + * input may contain promises and/or values, and reduceFunc + * may return either a value or a promise, *and* initialValue may + * be a promise for the starting value. + * + * @param {Array|Promise} promises array or promise for an array of anything, + * may contain a mix of promises and values. + * @param {function} f reduce function reduce(currentValue, nextValue, index) + * @returns {Promise} that will resolve to the final reduced value */ - function toFulfilledState(x) { - return { state: 'fulfilled', value: x }; - } - - /** - * Creates a rejected state snapshot - * @private - * @param {*} x any reason - * @returns {{state:'rejected',reason:*}} - */ - function toRejectedState(x) { - return { state: 'rejected', reason: x }; - } - - /** - * Creates a pending state snapshot - * @private - * @returns {{state:'pending'}} - */ - function toPendingState() { - return { state: 'pending' }; - } - - // - // Internals, utilities, etc. - // - - var promisePrototype, makePromisePrototype, reduceArray, slice, fcall, nextTick, handlerQueue, - funcProto, call, arrayProto, monitorApi, - capturedSetTimeout, cjsRequire, MutationObs, undef; - - cjsRequire = require; - - // - // Shared handler queue processing - // - // Credit to Twisol (https://github.com/Twisol) for suggesting - // this type of extensible queue + trampoline approach for - // next-tick conflation. - - handlerQueue = []; - - /** - * Enqueue a task. If the queue is not currently scheduled to be - * drained, schedule it. - * @param {function} task - */ - function enqueue(task) { - if(handlerQueue.push(task) === 1) { - nextTick(drainQueue); - } - } - - /** - * Drain the handler queue entirely, being careful to allow the - * queue to be extended while it is being processed, and to continue - * processing until it is truly empty. - */ - function drainQueue() { - runHandlers(handlerQueue); - handlerQueue = []; - } - - // Allow attaching the monitor to when() if env has no console - monitorApi = typeof console !== 'undefined' ? console : when; - - // Sniff "best" async scheduling option - // Prefer process.nextTick or MutationObserver, then check for - // vertx and finally fall back to setTimeout - /*global process,document,setTimeout,MutationObserver,WebKitMutationObserver*/ - if (typeof process === 'object' && process.nextTick) { - nextTick = process.nextTick; - } else if(MutationObs = - (typeof MutationObserver === 'function' && MutationObserver) || - (typeof WebKitMutationObserver === 'function' && WebKitMutationObserver)) { - nextTick = (function(document, MutationObserver, drainQueue) { - var el = document.createElement('div'); - new MutationObserver(drainQueue).observe(el, { attributes: true }); - - return function() { - el.setAttribute('x', 'x'); - }; - }(document, MutationObs, drainQueue)); - } else { - try { - // vert.x 1.x || 2.x - nextTick = cjsRequire('vertx').runOnLoop || cjsRequire('vertx').runOnContext; - } catch(ignore) { - // capture setTimeout to avoid being caught by fake timers - // used in time based tests - capturedSetTimeout = setTimeout; - nextTick = function(t) { capturedSetTimeout(t, 0); }; - } - } - - // - // Capture/polyfill function and array utils - // - - // Safe function calls - funcProto = Function.prototype; - call = funcProto.call; - fcall = funcProto.bind - ? call.bind(call) - : function(f, context) { - return f.apply(context, slice.call(arguments, 2)); - }; - - // Safe array ops - arrayProto = []; - slice = arrayProto.slice; - - // ES5 reduce implementation if native not available - // See: http://es5.github.com/#x15.4.4.21 as there are many - // specifics and edge cases. ES5 dictates that reduce.length === 1 - // This implementation deviates from ES5 spec in the following ways: - // 1. It does not check if reduceFunc is a Callable - reduceArray = arrayProto.reduce || - function(reduceFunc /*, initialValue */) { - /*jshint maxcomplexity: 7*/ - var arr, args, reduced, len, i; - - i = 0; - arr = Object(this); - len = arr.length >>> 0; - args = arguments; - - // If no initialValue, use first item of array (we know length !== 0 here) - // and adjust i to start at second item - if(args.length <= 1) { - // Skip to the first real element in the array - for(;;) { - if(i in arr) { - reduced = arr[i++]; - break; - } - - // If we reached the end of the array without finding any real - // elements, it's a TypeError - if(++i >= len) { - throw new TypeError(); - } - } - } else { - // If initialValue provided, use it - reduced = args[1]; - } - - // Do the actual reduce - for(;i < len; ++i) { - if(i in arr) { - reduced = reduceFunc(reduced, arr[i], i, arr); - } - } - - return reduced; - }; - - function identity(x) { - return x; - } - - function crash(fatalError) { - if(typeof monitorApi.reportUnhandled === 'function') { - monitorApi.reportUnhandled(); - } else { - enqueue(function() { - throw fatalError; - }); - } - - throw fatalError; + function reduceRight(promises, f /*, initialValue */) { + /*jshint unused:false*/ + var args = slice.call(arguments, 1); + return when(promises, function(array) { + args.unshift(array); + return Promise.reduceRight.apply(Promise, args); + }); } return when; }); -})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }); +})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(_dereq_); }); -},{"__browserify_process":3}],5:[function(require,module,exports){ +},{"./lib/Promise":4,"./lib/TimeoutError":6,"./lib/decorators/array":8,"./lib/decorators/flow":9,"./lib/decorators/fold":10,"./lib/decorators/inspect":11,"./lib/decorators/iterate":12,"./lib/decorators/progress":13,"./lib/decorators/timed":14,"./lib/decorators/unhandledRejection":15,"./lib/decorators/with":16}],21:[function(_dereq_,module,exports){ /*global module:true, require:false*/ -var bane = require("bane"); -var websocket = require("../lib/websocket/"); -var when = require("when"); +var bane = _dereq_("bane"); +var websocket = _dereq_("../lib/websocket/"); +var when = _dereq_("when"); function Mopidy(settings) { if (!(this instanceof Mopidy)) { @@ -1193,13 +2352,27 @@ function Mopidy(settings) { } } +Mopidy.ConnectionError = function (message) { + this.name = "ConnectionError"; + this.message = message; +}; +Mopidy.ConnectionError.prototype = new Error(); +Mopidy.ConnectionError.prototype.constructor = Mopidy.ConnectionError; + +Mopidy.ServerError = function (message) { + this.name = "ServerError"; + this.message = message; +}; +Mopidy.ServerError.prototype = new Error(); +Mopidy.ServerError.prototype.constructor = Mopidy.ServerError; + Mopidy.WebSocket = websocket.Client; Mopidy.prototype._configure = function (settings) { var currentHost = (typeof document !== "undefined" && document.location.host) || "localhost"; settings.webSocketUrl = settings.webSocketUrl || - "ws://" + currentHost + "/mopidy/ws/"; + "ws://" + currentHost + "/mopidy/ws"; if (settings.autoConnect !== false) { settings.autoConnect = true; @@ -1271,10 +2444,9 @@ Mopidy.prototype._cleanup = function (closeEvent) { Object.keys(this._pendingRequests).forEach(function (requestId) { var resolver = this._pendingRequests[requestId]; delete this._pendingRequests[requestId]; - resolver.reject({ - message: "WebSocket closed", - closeEvent: closeEvent - }); + var error = new Mopidy.ConnectionError("WebSocket closed"); + error.closeEvent = closeEvent; + resolver.reject(error); }.bind(this)); this.emit("state:offline"); @@ -1310,33 +2482,25 @@ Mopidy.prototype._handleWebSocketError = function (error) { }; Mopidy.prototype._send = function (message) { - var deferred = when.defer(); - switch (this._webSocket.readyState) { case Mopidy.WebSocket.CONNECTING: - deferred.resolver.reject({ - message: "WebSocket is still connecting" - }); - break; + return when.reject( + new Mopidy.ConnectionError("WebSocket is still connecting")); case Mopidy.WebSocket.CLOSING: - deferred.resolver.reject({ - message: "WebSocket is closing" - }); - break; + return when.reject( + new Mopidy.ConnectionError("WebSocket is closing")); case Mopidy.WebSocket.CLOSED: - deferred.resolver.reject({ - message: "WebSocket is closed" - }); - break; + return when.reject( + new Mopidy.ConnectionError("WebSocket is closed")); default: + var deferred = when.defer(); message.jsonrpc = "2.0"; message.id = this._nextRequestId(); this._pendingRequests[message.id] = deferred.resolver; this._webSocket.send(JSON.stringify(message)); this.emit("websocket:outgoingMessage", message); + return deferred.promise; } - - return deferred.promise; }; Mopidy.prototype._nextRequestId = (function () { @@ -1377,19 +2541,22 @@ Mopidy.prototype._handleResponse = function (responseMessage) { return; } + var error; var resolver = this._pendingRequests[responseMessage.id]; delete this._pendingRequests[responseMessage.id]; if (responseMessage.hasOwnProperty("result")) { resolver.resolve(responseMessage.result); } else if (responseMessage.hasOwnProperty("error")) { - resolver.reject(responseMessage.error); + error = new Mopidy.ServerError(responseMessage.error.message); + error.code = responseMessage.error.code; + error.data = responseMessage.error.data; + resolver.reject(error); this._console.warn("Server returned error:", responseMessage.error); } else { - resolver.reject({ - message: "Response without 'result' or 'error' received", - data: {response: responseMessage} - }); + error = new Error("Response without 'result' or 'error' received"); + error.data = {response: responseMessage}; + resolver.reject(error); this._console.warn( "Response without 'result' or 'error' received. Message was:", responseMessage); @@ -1460,6 +2627,6 @@ Mopidy.prototype._snakeToCamel = function (name) { module.exports = Mopidy; -},{"../lib/websocket/":1,"bane":2,"when":4}]},{},[5]) -(5) +},{"../lib/websocket/":1,"bane":2,"when":20}]},{},[21]) +(21) }); \ No newline at end of file diff --git a/mopidy/http/data/mopidy.min.js b/mopidy/http/data/mopidy.min.js index 450911bd..994a7754 100644 --- a/mopidy/http/data/mopidy.min.js +++ b/mopidy/http/data/mopidy.min.js @@ -1,5 +1,5 @@ -/*! Mopidy.js - built 2014-01-04 +/*! Mopidy.js v0.3.0 - built 2014-06-16 * http://www.mopidy.com/ * Copyright (c) 2014 Stein Magnus Jodal and contributors * Licensed under the Apache License, Version 2.0 */ -!function(a){if("object"==typeof exports)module.exports=a();else if("function"==typeof define&&define.amd)define(a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.Mopidy=a()}}(function(){var a;return function b(a,c,d){function e(g,h){if(!c[g]){if(!a[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};a[g][0].call(j.exports,function(b){var c=a[g][1][b];return e(c?c:b)},j,j.exports,b,a,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g0)for(d=0;e>d;++d)c[d](a,b);else setTimeout(function(){throw b.message=a+" listener threw error: "+b.message,b},0)}function b(a){if("function"!=typeof a)throw new TypeError("Listener is not function");return a}function c(a){return a.supervisors||(a.supervisors=[]),a.supervisors}function d(a,b){return a.listeners||(a.listeners={}),b&&!a.listeners[b]&&(a.listeners[b]=[]),b?a.listeners[b]:a.listeners}function e(a){return a.errbacks||(a.errbacks=[]),a.errbacks}function f(f){function h(b,c,d){try{c.listener.apply(c.thisp||f,d)}catch(g){a(b,g,e(f))}}return f=f||{},f.on=function(a,e,f){return"function"==typeof a?c(this).push({listener:a,thisp:e}):(d(this,a).push({listener:b(e),thisp:f}),void 0)},f.off=function(a,b){var f,g,h,i;if(!a){f=c(this),f.splice(0,f.length),g=d(this);for(h in g)g.hasOwnProperty(h)&&(f=d(this,h),f.splice(0,f.length));return f=e(this),f.splice(0,f.length),void 0}if("function"==typeof a?(f=c(this),b=a):f=d(this,a),!b)return f.splice(0,f.length),void 0;for(h=0,i=f.length;i>h;++h)if(f[h].listener===b)return f.splice(h,1),void 0},f.once=function(a,b,c){var d=function(){f.off(a,d),b.apply(this,arguments)};f.on(a,d,c)},f.bind=function(a,b){var c,d,e;if(b)for(d=0,e=b.length;e>d;++d){if("function"!=typeof a[b[d]])throw new Error("No such method "+b[d]);this.on(b[d],a[b[d]],a)}else for(c in a)"function"==typeof a[c]&&this.on(c,a[c],a);return a},f.emit=function(a){var b,e,f=c(this),i=g.call(arguments);for(b=0,e=f.length;e>b;++b)h(a,f[b],i);for(f=d(this,a).slice(),i=g.call(arguments,1),b=0,e=f.length;e>b;++b)h(a,f[b],i)},f.errback=function(a){this.errbacks||(this.errbacks=[]),this.errbacks.push(b(a))},f}var g=Array.prototype.slice;return{createEventEmitter:f,aggregate:function(a){var b=f();return a.forEach(function(a){a.on(function(a,c){b.emit(a,c)})}),b}}})},{}],3:[function(a,b){var c=b.exports={};c.nextTick=function(){var a="undefined"!=typeof window&&window.setImmediate,b="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(a)return function(a){return window.setImmediate(a)};if(b){var c=[];return window.addEventListener("message",function(a){var b=a.source;if((b===window||null===b)&&"process-tick"===a.data&&(a.stopPropagation(),c.length>0)){var d=c.shift();d()}},!0),function(a){c.push(a),window.postMessage("process-tick","*")}}return function(a){setTimeout(a,0)}}(),c.title="browser",c.browser=!0,c.env={},c.argv=[],c.binding=function(){throw new Error("process.binding is not supported")},c.cwd=function(){return"/"},c.chdir=function(){throw new Error("process.chdir is not supported")}},{}],4:[function(b,c){var d=b("__browserify_process");!function(a){"use strict";a(function(a){function b(a,b,c,d){return f(a).then(b,c,d)}function c(a){return new e(a,Q.PromiseStatus&&Q.PromiseStatus())}function e(a,b){function c(){return i?i.inspect():B()}function d(a,b,c,d,e){function f(f){f._when(a,b,c,d,e)}l?l.push(f):C(function(){f(i)})}function e(a){if(l){var c=l;l=U,C(function(){i=k(h,a),b&&p(i,b),j(c,i)})}}function f(a){e(new n(a))}function g(a){if(l){var b=l;C(function(){j(b,new o(a))})}}var h,i,l=[];h=this,this._status=b,this.inspect=c,this._when=d;try{a(e,f,g)}catch(m){f(m)}}function f(a){return a instanceof e?a:g(a)}function g(a){return c(function(b){b(a)})}function h(a){return b(a,function(a){return new n(a)})}function i(){function a(a,c,f){b.resolve=b.resolver.resolve=function(b){return e?g(b):(e=!0,a(b),d)},b.reject=b.resolver.reject=function(a){return e?g(new n(a)):(e=!0,c(a),d)},b.notify=b.resolver.notify=function(a){return f(a),a}}var b,d,e;return b={promise:U,resolve:U,reject:U,notify:U,resolver:{resolve:U,reject:U,notify:U}},b.promise=d=c(a),b}function j(a,b){for(var c=0;c>>0,i=Math.max(0,Math.min(d,o)),k=[],j=o-i+1,l=[],i)for(n=function(a){l.push(a),--j||(m=n=E,e(l))},m=function(a){k.push(a),--i||(m=n=E,c(k))},p=0;o>p;++p)p in a&&b(a[p],h,g,f);else c(k)}return c(h).then(e,f,g)})}function s(a,b,c,d){function e(a){return b?b(a[0]):a[0]}return r(a,1,e,c,d)}function t(a,b,c,d){return x(a,E).then(b,c,d)}function u(){return x(arguments,E)}function v(a){return x(a,z,A)}function w(a,b){return x(a,b)}function x(a,c,d){return b(a,function(a){function f(e,f,g){function h(a,h){b(a,c,d).then(function(a){i[h]=a,--k||e(i)},f,g)}var i,j,k,l;if(k=j=a.length>>>0,i=[],!k)return e(i),void 0;for(l=0;j>l;l++)l in a?h(a[l],l):--k}return new e(f)})}function y(a,c){var d=K(J,arguments,1);return b(a,function(a){var e;return e=a.length,d[0]=function(a,d,f){return b(a,function(a){return b(d,function(b){return c(a,b,f,e)})})},I.apply(a,d)})}function z(a){return{state:"fulfilled",value:a}}function A(a){return{state:"rejected",reason:a}}function B(){return{state:"pending"}}function C(a){1===M.push(a)&&L(D)}function D(){j(M),M=[]}function E(a){return a}function F(a){throw"function"==typeof Q.reportUnhandled?Q.reportUnhandled():C(function(){throw a}),a}b.promise=c,b.resolve=g,b.reject=h,b.defer=i,b.join=u,b.all=t,b.map=w,b.reduce=y,b.settle=v,b.any=s,b.some=r,b.isPromise=q,b.isPromiseLike=q,G=e.prototype,G.then=function(a,b,c){var d=this;return new e(function(e,f,g){d._when(e,g,a,b,c)},this._status&&this._status.observed())},G["catch"]=G.otherwise=function(a){return this.then(U,a)},G["finally"]=G.ensure=function(a){function b(){return g(a())}return"function"==typeof a?this.then(b,b).yield(this):this},G.done=function(a,b){this.then(a,b)["catch"](F)},G.yield=function(a){return this.then(function(){return a})},G.tap=function(a){return this.then(a).yield(this)},G.spread=function(a){return this.then(function(b){return t(b,function(b){return a.apply(U,b)})})},G.always=function(a,b){return this.then(a,a,b)},H=Object.create||function(a){function b(){}return b.prototype=a,new b},m.prototype=H(G),m.prototype.inspect=function(){return z(this.value)},m.prototype._when=function(a,b,c){try{a("function"==typeof c?c(this.value):this.value)}catch(d){a(new n(d))}},n.prototype=H(G),n.prototype.inspect=function(){return A(this.value)},n.prototype._when=function(a,b,c,d){try{a("function"==typeof d?d(this.value):this)}catch(e){a(new n(e))}},o.prototype=H(G),o.prototype._when=function(a,b,c,d,e){try{b("function"==typeof e?e(this.value):this.value)}catch(f){b(f)}};var G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U;if(S=a,M=[],Q="undefined"!=typeof console?console:b,"object"==typeof d&&d.nextTick)L=d.nextTick;else if(T="function"==typeof MutationObserver&&MutationObserver||"function"==typeof WebKitMutationObserver&&WebKitMutationObserver)L=function(a,b,c){var d=a.createElement("div");return new b(c).observe(d,{attributes:!0}),function(){d.setAttribute("x","x")}}(document,T,D);else try{L=S("vertx").runOnLoop||S("vertx").runOnContext}catch(V){R=setTimeout,L=function(a){R(a,0)}}return N=Function.prototype,O=N.call,K=N.bind?O.bind(O):function(a,b){return a.apply(b,J.call(arguments,2))},P=[],J=P.slice,I=P.reduce||function(a){var b,c,d,e,f;if(f=0,b=Object(this),e=b.length>>>0,c=arguments,c.length<=1)for(;;){if(f in b){d=b[f++];break}if(++f>=e)throw new TypeError}else d=c[1];for(;e>f;++f)f in b&&(d=a(d,b[f],f,b));return d},b})}("function"==typeof a&&a.amd?a:function(a){c.exports=a(b)})},{__browserify_process:3}],5:[function(a,b){function c(a){return this instanceof c?(this._settings=this._configure(a||{}),this._console=this._getConsole(),this._backoffDelay=this._settings.backoffDelayMin,this._pendingRequests={},this._webSocket=null,d.createEventEmitter(this),this._delegateEvents(),this._settings.autoConnect&&this.connect(),void 0):new c(a)}var d=a("bane"),e=a("../lib/websocket/"),f=a("when");c.WebSocket=e.Client,c.prototype._configure=function(a){var b="undefined"!=typeof document&&document.location.host||"localhost";return a.webSocketUrl=a.webSocketUrl||"ws://"+b+"/mopidy/ws/",a.autoConnect!==!1&&(a.autoConnect=!0),a.backoffDelayMin=a.backoffDelayMin||1e3,a.backoffDelayMax=a.backoffDelayMax||64e3,a},c.prototype._getConsole=function(){var a="undefined"!=typeof a&&a||{};return a.log=a.log||function(){},a.warn=a.warn||function(){},a.error=a.error||function(){},a},c.prototype._delegateEvents=function(){this.off("websocket:close"),this.off("websocket:error"),this.off("websocket:incomingMessage"),this.off("websocket:open"),this.off("state:offline"),this.on("websocket:close",this._cleanup),this.on("websocket:error",this._handleWebSocketError),this.on("websocket:incomingMessage",this._handleMessage),this.on("websocket:open",this._resetBackoffDelay),this.on("websocket:open",this._getApiSpec),this.on("state:offline",this._reconnect)},c.prototype.connect=function(){if(this._webSocket){if(this._webSocket.readyState===c.WebSocket.OPEN)return;this._webSocket.close()}this._webSocket=this._settings.webSocket||new c.WebSocket(this._settings.webSocketUrl),this._webSocket.onclose=function(a){this.emit("websocket:close",a)}.bind(this),this._webSocket.onerror=function(a){this.emit("websocket:error",a)}.bind(this),this._webSocket.onopen=function(){this.emit("websocket:open")}.bind(this),this._webSocket.onmessage=function(a){this.emit("websocket:incomingMessage",a)}.bind(this)},c.prototype._cleanup=function(a){Object.keys(this._pendingRequests).forEach(function(b){var c=this._pendingRequests[b];delete this._pendingRequests[b],c.reject({message:"WebSocket closed",closeEvent:a})}.bind(this)),this.emit("state:offline")},c.prototype._reconnect=function(){this.emit("reconnectionPending",{timeToAttempt:this._backoffDelay}),setTimeout(function(){this.emit("reconnecting"),this.connect()}.bind(this),this._backoffDelay),this._backoffDelay=2*this._backoffDelay,this._backoffDelay>this._settings.backoffDelayMax&&(this._backoffDelay=this._settings.backoffDelayMax)},c.prototype._resetBackoffDelay=function(){this._backoffDelay=this._settings.backoffDelayMin},c.prototype.close=function(){this.off("state:offline",this._reconnect),this._webSocket.close()},c.prototype._handleWebSocketError=function(a){this._console.warn("WebSocket error:",a.stack||a)},c.prototype._send=function(a){var b=f.defer();switch(this._webSocket.readyState){case c.WebSocket.CONNECTING:b.resolver.reject({message:"WebSocket is still connecting"});break;case c.WebSocket.CLOSING:b.resolver.reject({message:"WebSocket is closing"});break;case c.WebSocket.CLOSED:b.resolver.reject({message:"WebSocket is closed"});break;default:a.jsonrpc="2.0",a.id=this._nextRequestId(),this._pendingRequests[a.id]=b.resolver,this._webSocket.send(JSON.stringify(a)),this.emit("websocket:outgoingMessage",a)}return b.promise},c.prototype._nextRequestId=function(){var a=-1;return function(){return a+=1}}(),c.prototype._handleMessage=function(a){try{var b=JSON.parse(a.data);b.hasOwnProperty("id")?this._handleResponse(b):b.hasOwnProperty("event")?this._handleEvent(b):this._console.warn("Unknown message type received. Message was: "+a.data)}catch(c){if(!(c instanceof SyntaxError))throw c;this._console.warn("WebSocket message parsing failed. Message was: "+a.data)}},c.prototype._handleResponse=function(a){if(!this._pendingRequests.hasOwnProperty(a.id))return this._console.warn("Unexpected response received. Message was:",a),void 0;var b=this._pendingRequests[a.id];delete this._pendingRequests[a.id],a.hasOwnProperty("result")?b.resolve(a.result):a.hasOwnProperty("error")?(b.reject(a.error),this._console.warn("Server returned error:",a.error)):(b.reject({message:"Response without 'result' or 'error' received",data:{response:a}}),this._console.warn("Response without 'result' or 'error' received. Message was:",a))},c.prototype._handleEvent=function(a){var b=a.event,c=a;delete c.event,this.emit("event:"+this._snakeToCamel(b),c)},c.prototype._getApiSpec=function(){return this._send({method:"core.describe"}).then(this._createApi.bind(this),this._handleWebSocketError).then(null,this._handleWebSocketError)},c.prototype._createApi=function(a){var b=function(a){return function(){var b=Array.prototype.slice.call(arguments);return this._send({method:a,params:b})}.bind(this)}.bind(this),c=function(a){var b=a.split(".");return b.length>=1&&"core"===b[0]&&(b=b.slice(1)),b},d=function(a){var b=this;return a.forEach(function(a){a=this._snakeToCamel(a),b[a]=b[a]||{},b=b[a]}.bind(this)),b}.bind(this),e=function(e){var f=c(e),g=this._snakeToCamel(f.slice(-1)[0]),h=d(f.slice(0,-1));h[g]=b(e),h[g].description=a[e].description,h[g].params=a[e].params}.bind(this);Object.keys(a).forEach(e),this.emit("state:online")},c.prototype._snakeToCamel=function(a){return a.replace(/(_[a-z])/g,function(a){return a.toUpperCase().replace("_","")})},b.exports=c},{"../lib/websocket/":1,bane:2,when:4}]},{},[5])(5)}); \ No newline at end of file +!function(a){if("object"==typeof exports)module.exports=a();else if("function"==typeof define&&define.amd)define(a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.Mopidy=a()}}(function(){var a;return function b(a,c,d){function e(g,h){if(!c[g]){if(!a[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};a[g][0].call(j.exports,function(b){var c=a[g][1][b];return e(c?c:b)},j,j.exports,b,a,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g0)for(d=0;e>d;++d)c[d](a,b);else setTimeout(function(){throw b.message=a+" listener threw error: "+b.message,b},0)}function b(a){if("function"!=typeof a)throw new TypeError("Listener is not function");return a}function c(a){return a.supervisors||(a.supervisors=[]),a.supervisors}function d(a,b){return a.listeners||(a.listeners={}),b&&!a.listeners[b]&&(a.listeners[b]=[]),b?a.listeners[b]:a.listeners}function e(a){return a.errbacks||(a.errbacks=[]),a.errbacks}function f(f){function h(b,c,d){try{c.listener.apply(c.thisp||f,d)}catch(g){a(b,g,e(f))}}return f=f||{},f.on=function(a,e,f){return"function"==typeof a?c(this).push({listener:a,thisp:e}):void d(this,a).push({listener:b(e),thisp:f})},f.off=function(a,b){var f,g,h,i;if(!a){f=c(this),f.splice(0,f.length),g=d(this);for(h in g)g.hasOwnProperty(h)&&(f=d(this,h),f.splice(0,f.length));return f=e(this),void f.splice(0,f.length)}if("function"==typeof a?(f=c(this),b=a):f=d(this,a),!b)return void f.splice(0,f.length);for(h=0,i=f.length;i>h;++h)if(f[h].listener===b)return void f.splice(h,1)},f.once=function(a,b,c){var d=function(){f.off(a,d),b.apply(this,arguments)};f.on(a,d,c)},f.bind=function(a,b){var c,d,e;if(b)for(d=0,e=b.length;e>d;++d){if("function"!=typeof a[b[d]])throw new Error("No such method "+b[d]);this.on(b[d],a[b[d]],a)}else for(c in a)"function"==typeof a[c]&&this.on(c,a[c],a);return a},f.emit=function(a){var b,e,f=c(this),i=g.call(arguments);for(b=0,e=f.length;e>b;++b)h(a,f[b],i);for(f=d(this,a).slice(),i=g.call(arguments,1),b=0,e=f.length;e>b;++b)h(a,f[b],i)},f.errback=function(a){this.errbacks||(this.errbacks=[]),this.errbacks.push(b(a))},f}var g=Array.prototype.slice;return{createEventEmitter:f,aggregate:function(a){var b=f();return a.forEach(function(a){a.on(function(a,c){b.emit(a,c)})}),b}}})},{}],3:[function(a,b){function c(){}var d=b.exports={};d.nextTick=function(){var a="undefined"!=typeof window&&window.setImmediate,b="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(a)return function(a){return window.setImmediate(a)};if(b){var c=[];return window.addEventListener("message",function(a){var b=a.source;if((b===window||null===b)&&"process-tick"===a.data&&(a.stopPropagation(),c.length>0)){var d=c.shift();d()}},!0),function(a){c.push(a),window.postMessage("process-tick","*")}}return function(a){setTimeout(a,0)}}(),d.title="browser",d.browser=!0,d.env={},d.argv=[],d.on=c,d.addListener=c,d.once=c,d.off=c,d.removeListener=c,d.removeAllListeners=c,d.emit=c,d.binding=function(){throw new Error("process.binding is not supported")},d.cwd=function(){return"/"},d.chdir=function(){throw new Error("process.chdir is not supported")}},{}],4:[function(b,c){!function(a){"use strict";a(function(a){var b=a("./makePromise"),c=a("./scheduler"),d=a("./async");return b({scheduler:new c(d)})})}("function"==typeof a&&a.amd?a:function(a){c.exports=a(b)})},{"./async":7,"./makePromise":17,"./scheduler":18}],5:[function(b,c){!function(a){"use strict";a(function(){function a(a){this.head=this.tail=this.length=0,this.buffer=new Array(1<f;++f)e[f]=d[f];else{for(a=d.length,b=this.tail;a>c;++f,++c)e[f]=d[c];for(c=0;b>c;++f,++c)e[f]=d[c]}this.buffer=e,this.head=0,this.tail=this.length},a})}("function"==typeof a&&a.amd?a:function(a){c.exports=a()})},{}],6:[function(b,c){!function(a){"use strict";a(function(){function a(b){Error.call(this),this.message=b,this.name=a.name,"function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,a)}return a.prototype=Object.create(Error.prototype),a.prototype.constructor=a,a})}("function"==typeof a&&a.amd?a:function(a){c.exports=a()})},{}],7:[function(b,c){(function(d){!function(a){"use strict";a(function(a){var b,c;return b="undefined"!=typeof d&&null!==d&&"function"==typeof d.nextTick?function(a){d.nextTick(a)}:(c="function"==typeof MutationObserver&&MutationObserver||"function"==typeof WebKitMutationObserver&&WebKitMutationObserver)?function(a,b){function c(){var a=d;d=void 0,a()}var d,e=a.createElement("div"),f=new b(c);return f.observe(e,{attributes:!0}),function(a){d=a,e.setAttribute("class","x")}}(document,c):function(a){try{return a("vertx").runOnLoop||a("vertx").runOnContext}catch(b){}var c=setTimeout;return function(a){c(a,0)}}(a)})}("function"==typeof a&&a.amd?a:function(a){c.exports=a(b)})}).call(this,b("FWaASH"))},{FWaASH:3}],8:[function(b,c){!function(a){"use strict";a(function(){return function(a){function b(b){return new a(function(a,c){function d(a){f.push(a),0===--e&&c(f)}var e=0,f=[];k.call(b,function(b){++e,l(b).then(a,d)}),0===e&&a()})}function c(b,c){return new a(function(a,d,e){function f(b){i>0&&(--i,j.push(b),0===i&&a(j))}function g(a){h>0&&(--h,m.push(a),0===h&&d(m))}var h,i=0,j=[],m=[];return k.call(b,function(a){++i,l(a).then(f,g,e)}),c=Math.max(c,0),h=i-c+1,i=Math.min(c,i),0===i?void a(j):void 0})}function d(a,b,c){return m(h.call(a,function(a){return l(a).then(b,c)}))}function e(a){return m(h.call(a,function(a){function b(){return a.inspect()}return a=l(a),a.then(b,b)}))}function f(a,b){function c(a,c,d){return l(a).then(function(a){return l(c).then(function(c){return b(a,c,d)})})}return arguments.length>2?i.call(a,c,arguments[2]):i.call(a,c)}function g(a,b){function c(a,c,d){return l(a).then(function(a){return l(c).then(function(c){return b(a,c,d)})})}return arguments.length>2?j.call(a,c,arguments[2]):j.call(a,c)}var h=Array.prototype.map,i=Array.prototype.reduce,j=Array.prototype.reduceRight,k=Array.prototype.forEach,l=a.resolve,m=a.all;return a.any=b,a.some=c,a.settle=e,a.map=d,a.reduce=f,a.reduceRight=g,a.prototype.spread=function(a){return this.then(m).then(function(b){return a.apply(void 0,b)})},a}})}("function"==typeof a&&a.amd?a:function(a){c.exports=a()})},{}],9:[function(b,c){!function(a){"use strict";a(function(){function a(){throw new TypeError("catch predicate must be a function")}function b(a,b){return c(b)?a instanceof b:b(a)}function c(a){return a===Error||null!=a&&a.prototype instanceof Error}function d(a,b){return function(){return a.call(this),b}}function e(){}return function(c){function f(a,c){return function(d){return b(d,c)?a.call(this,d):g(d)}}var g=c.reject,h=c.prototype["catch"];return c.prototype.done=function(a,b){var c=this._handler;c.when({resolve:this._maybeFatal,notify:e,context:this,receiver:c.receiver,fulfilled:a,rejected:b,progress:void 0})},c.prototype["catch"]=c.prototype.otherwise=function(b){return 1===arguments.length?h.call(this,b):"function"!=typeof b?this.ensure(a):h.call(this,f(arguments[1],b))},c.prototype["finally"]=c.prototype.ensure=function(a){return"function"!=typeof a?this:(a=d(a,this),this.then(a,a))},c.prototype["else"]=c.prototype.orElse=function(a){return this.then(void 0,function(){return a})},c.prototype["yield"]=function(a){return this.then(function(){return a})},c.prototype.tap=function(a){return this.then(a)["yield"](this)},c}})}("function"==typeof a&&a.amd?a:function(a){c.exports=a()})},{}],10:[function(b,c){!function(a){"use strict";a(function(){return function(a){return a.prototype.fold=function(a,b){var c=this._beget();return this._handler.fold(c._handler,a,b),c},a}})}("function"==typeof a&&a.amd?a:function(a){c.exports=a()})},{}],11:[function(b,c){!function(a){"use strict";a(function(){return function(a){return a.prototype.inspect=function(){return this._handler.inspect()},a}})}("function"==typeof a&&a.amd?a:function(a){c.exports=a()})},{}],12:[function(b,c){!function(a){"use strict";a(function(){return function(a){function b(a,b,d,e){return c(function(b){return[b,a(b)]},b,d,e)}function c(a,b,e,f){function g(f,g){return d(e(f)).then(function(){return c(a,b,e,g)})}return d(f).then(function(c){return d(b(c)).then(function(b){return b?c:d(a(c)).spread(g)})})}var d=a.resolve;return a.iterate=b,a.unfold=c,a}})}("function"==typeof a&&a.amd?a:function(a){c.exports=a()})},{}],13:[function(b,c){!function(a){"use strict";a(function(){return function(a){return a.prototype.progress=function(a){return this.then(void 0,void 0,a)},a}})}("function"==typeof a&&a.amd?a:function(a){c.exports=a()})},{}],14:[function(b,c){!function(a){"use strict";a(function(a){var b=a("../timer"),c=a("../TimeoutError");return function(a){return a.prototype.delay=function(a){var c=this._beget(),d=c._handler;return this._handler.map(function(c){b.set(function(){d.resolve(c)},a)},d),c},a.prototype.timeout=function(a,d){function e(){h.reject(f?d:new c("timed out after "+a+"ms"))}var f=arguments.length>1,g=this._beget(),h=g._handler,i=b.set(e,a);return this._handler.chain(h,function(a){b.clear(i),this.resolve(a)},function(a){b.clear(i),this.reject(a)},h.notify),g},a}})}("function"==typeof a&&a.amd?a:function(a){c.exports=a(b)})},{"../TimeoutError":6,"../timer":19}],15:[function(b,c){!function(a){"use strict";a(function(a){function b(a){var b="object"==typeof a&&a.stack?a.stack:c(a);return a instanceof Error?b:b+" (WARNING: non-Error used)"}function c(a){var b=String(a);return"[object Object]"===b&&"undefined"!=typeof JSON&&(b=d(a,b)),b}function d(a,b){try{return JSON.stringify(a)}catch(a){return b}}function e(a){throw a}function f(){}var g=a("../timer");return function(a){function d(a){a.handled||(n.push(a),k("Potentially unhandled rejection ["+a.id+"] "+b(a.value)))}function h(a){var b=n.indexOf(a);b>=0&&(n.splice(b,1),l("Handled previous rejection ["+a.id+"] "+c(a.value)))}function i(a,b){m.push(a,b),o||(o=!0,o=g.set(j,0))}function j(){for(o=!1;m.length>0;)m.shift()(m.shift())}var k=f,l=f;"undefined"!=typeof console&&(k="undefined"!=typeof console.error?function(a){console.error(a)}:function(a){console.log(a)},l="undefined"!=typeof console.info?function(a){console.info(a)}:function(a){console.log(a)}),a.onPotentiallyUnhandledRejection=function(a){i(d,a)},a.onPotentiallyUnhandledRejectionHandled=function(a){i(h,a)},a.onFatalRejection=function(a){i(e,a.value)};var m=[],n=[],o=!1;return a}})}("function"==typeof a&&a.amd?a:function(a){c.exports=a(b)})},{"../timer":19}],16:[function(b,c){!function(a){"use strict";a(function(){return function(a){return a.prototype["with"]=a.prototype.withThis=a.prototype._bindContext,a}})}("function"==typeof a&&a.amd?a:function(a){c.exports=a()})},{}],17:[function(b,c){!function(a){"use strict";a(function(){return function(a){function b(a,b){this._handler=a===m?b:c(a)}function c(a){function b(a){e.resolve(a)}function c(a){e.reject(a)}function d(a){e.notify(a)}var e=new n;try{a(b,c,d)}catch(f){c(f)}return e}function d(a){return k(a)?a:new b(m,new p(j(a)))}function e(a){return new b(m,new p(new t(a)))}function f(){return M}function g(){return new b(m,new n)}function h(a){function c(a,b,c,d){c.map(function(a){b[d]=a,0===--i&&this.become(new s(b))},a)}var d,e,f,g,h=new n,i=a.length>>>0,j=new Array(i);for(d=0;d0)){h.become(e);break}j[d]=e.value,--i}else j[d]=f,--i;else--i;return 0===i&&h.become(new s(j)),new b(m,h)}function i(a){if(Object(a)===a&&0===a.length)return f();var c,d,e=new n;for(c=0;c0)return new b(m,d);var e=this._beget(),f=e._handler;return d.when({resolve:f.resolve,notify:f.notify,context:f,receiver:d.receiver,fulfilled:a,rejected:c,progress:arguments.length>2?arguments[2]:void 0}),e},b.prototype["catch"]=function(a){return this.then(void 0,a)},b.prototype._bindContext=function(a){return new b(m,new q(this._handler,a))},b.prototype._beget=function(){var a=this._handler,b=new n(a.receiver,a.join().context);return new this.constructor(m,b)},b.prototype._maybeFatal=function(a){if(C(a)){var b=j(a),c=this._handler.context;b.catchError(function(){this._fatal(c)},b)}},b.all=h,b.race=i,m.prototype.when=m.prototype.resolve=m.prototype.reject=m.prototype.notify=m.prototype._fatal=m.prototype._unreport=m.prototype._report=H,m.prototype.inspect=x,m.prototype._state=0,m.prototype.state=function(){return this._state},m.prototype.join=function(){for(var a=this;void 0!==a.handler;)a=a.handler;return a},m.prototype.chain=function(a,b,c,d){this.when({resolve:H,notify:H,context:void 0,receiver:a,fulfilled:b,rejected:c,progress:d})},m.prototype.map=function(a,b){this.chain(b,a,b.reject,b.notify)},m.prototype.catchError=function(a,b){this.chain(b,b.resolve,a,b.notify)},m.prototype.fold=function(a,b,c){this.join().map(function(a){j(c).map(function(c){this.resolve(E(b,c,a,this.receiver))},this)},a)},G(m,n),n.prototype._state=0,n.prototype.inspect=function(){return this.resolved?this.join().inspect():x()},n.prototype.resolve=function(a){this.resolved||this.become(j(a))},n.prototype.reject=function(a){this.resolved||this.become(new t(a))},n.prototype.join=function(){if(this.resolved){for(var a=this;void 0!==a.handler;)if(a=a.handler,a===this)return this.handler=new w;return a}return this},n.prototype.run=function(){var a=this.consumers,b=this.join();this.consumers=void 0;for(var c=0;c0;)a.shift().run();for(this._running=!1,a=this._afterQueue;a.length>0;)a.shift()(a.shift(),a.shift())},b})}("function"==typeof a&&a.amd?a:function(a){c.exports=a(b)})},{"./Queue":5}],19:[function(b,c){!function(a){"use strict";a(function(a){var b,c,d,e;b=a;try{c=b("vertx"),d=function(a,b){return c.setTimer(b,a)},e=c.cancelTimer}catch(f){d=function(a,b){return setTimeout(a,b)},e=function(a){return clearTimeout(a)}}return{set:d,clear:e}})}("function"==typeof a&&a.amd?a:function(a){c.exports=a(b)})},{}],20:[function(b,c){!function(a){"use strict";a(function(a){function b(a,b,c){var d=z.resolve(a);return arguments.length<2?d:arguments.length>3?d.then(b,c,arguments[3]):d.then(b,c)}function c(a){return new z(a)}function d(a){return function(){return f(a,this,A.call(arguments))}}function e(a){return f(a,this,A.call(arguments,1))}function f(a,b,c){return z.all(c).then(function(c){return a.apply(b,c)})}function g(){return new h}function h(){function a(a){d._handler.resolve(a)}function b(a){d._handler.reject(a)}function c(a){d._handler.notify(a)}var d=z._defer();this.promise=d,this.resolve=a,this.reject=b,this.notify=c,this.resolver={resolve:a,reject:b,notify:c}}function i(a){return a&&"function"==typeof a.then}function j(){return z.all(arguments)}function k(a){return b(a,z.all)}function l(a){return b(a,z.settle)}function m(a,c){return b(a,function(a){return z.map(a,c)})}function n(a){var c=A.call(arguments,1);return b(a,function(a){return c.unshift(a),z.reduce.apply(z,c)})}function o(a){var c=A.call(arguments,1);return b(a,function(a){return c.unshift(a),z.reduceRight.apply(z,c)})}var p=a("./lib/decorators/timed"),q=a("./lib/decorators/array"),r=a("./lib/decorators/flow"),s=a("./lib/decorators/fold"),t=a("./lib/decorators/inspect"),u=a("./lib/decorators/iterate"),v=a("./lib/decorators/progress"),w=a("./lib/decorators/with"),x=a("./lib/decorators/unhandledRejection"),y=a("./lib/TimeoutError"),z=[q,r,s,u,v,t,w,p,x].reduce(function(a,b){return b(a)},a("./lib/Promise")),A=Array.prototype.slice;return b.promise=c,b.resolve=z.resolve,b.reject=z.reject,b.lift=d,b["try"]=e,b.attempt=e,b.iterate=z.iterate,b.unfold=z.unfold,b.join=j,b.all=k,b.settle=l,b.any=d(z.any),b.some=d(z.some),b.map=m,b.reduce=n,b.reduceRight=o,b.isPromiseLike=i,b.Promise=z,b.defer=g,b.TimeoutError=y,b})}("function"==typeof a&&a.amd?a:function(a){c.exports=a(b)})},{"./lib/Promise":4,"./lib/TimeoutError":6,"./lib/decorators/array":8,"./lib/decorators/flow":9,"./lib/decorators/fold":10,"./lib/decorators/inspect":11,"./lib/decorators/iterate":12,"./lib/decorators/progress":13,"./lib/decorators/timed":14,"./lib/decorators/unhandledRejection":15,"./lib/decorators/with":16}],21:[function(a,b){function c(a){return this instanceof c?(this._settings=this._configure(a||{}),this._console=this._getConsole(),this._backoffDelay=this._settings.backoffDelayMin,this._pendingRequests={},this._webSocket=null,d.createEventEmitter(this),this._delegateEvents(),void(this._settings.autoConnect&&this.connect())):new c(a)}var d=a("bane"),e=a("../lib/websocket/"),f=a("when");c.ConnectionError=function(a){this.name="ConnectionError",this.message=a},c.ConnectionError.prototype=new Error,c.ConnectionError.prototype.constructor=c.ConnectionError,c.ServerError=function(a){this.name="ServerError",this.message=a},c.ServerError.prototype=new Error,c.ServerError.prototype.constructor=c.ServerError,c.WebSocket=e.Client,c.prototype._configure=function(a){var b="undefined"!=typeof document&&document.location.host||"localhost";return a.webSocketUrl=a.webSocketUrl||"ws://"+b+"/mopidy/ws",a.autoConnect!==!1&&(a.autoConnect=!0),a.backoffDelayMin=a.backoffDelayMin||1e3,a.backoffDelayMax=a.backoffDelayMax||64e3,a},c.prototype._getConsole=function(){var a="undefined"!=typeof a&&a||{};return a.log=a.log||function(){},a.warn=a.warn||function(){},a.error=a.error||function(){},a},c.prototype._delegateEvents=function(){this.off("websocket:close"),this.off("websocket:error"),this.off("websocket:incomingMessage"),this.off("websocket:open"),this.off("state:offline"),this.on("websocket:close",this._cleanup),this.on("websocket:error",this._handleWebSocketError),this.on("websocket:incomingMessage",this._handleMessage),this.on("websocket:open",this._resetBackoffDelay),this.on("websocket:open",this._getApiSpec),this.on("state:offline",this._reconnect)},c.prototype.connect=function(){if(this._webSocket){if(this._webSocket.readyState===c.WebSocket.OPEN)return;this._webSocket.close()}this._webSocket=this._settings.webSocket||new c.WebSocket(this._settings.webSocketUrl),this._webSocket.onclose=function(a){this.emit("websocket:close",a)}.bind(this),this._webSocket.onerror=function(a){this.emit("websocket:error",a)}.bind(this),this._webSocket.onopen=function(){this.emit("websocket:open")}.bind(this),this._webSocket.onmessage=function(a){this.emit("websocket:incomingMessage",a)}.bind(this)},c.prototype._cleanup=function(a){Object.keys(this._pendingRequests).forEach(function(b){var d=this._pendingRequests[b];delete this._pendingRequests[b];var e=new c.ConnectionError("WebSocket closed");e.closeEvent=a,d.reject(e)}.bind(this)),this.emit("state:offline")},c.prototype._reconnect=function(){this.emit("reconnectionPending",{timeToAttempt:this._backoffDelay}),setTimeout(function(){this.emit("reconnecting"),this.connect()}.bind(this),this._backoffDelay),this._backoffDelay=2*this._backoffDelay,this._backoffDelay>this._settings.backoffDelayMax&&(this._backoffDelay=this._settings.backoffDelayMax)},c.prototype._resetBackoffDelay=function(){this._backoffDelay=this._settings.backoffDelayMin},c.prototype.close=function(){this.off("state:offline",this._reconnect),this._webSocket.close()},c.prototype._handleWebSocketError=function(a){this._console.warn("WebSocket error:",a.stack||a)},c.prototype._send=function(a){switch(this._webSocket.readyState){case c.WebSocket.CONNECTING:return f.reject(new c.ConnectionError("WebSocket is still connecting"));case c.WebSocket.CLOSING:return f.reject(new c.ConnectionError("WebSocket is closing"));case c.WebSocket.CLOSED:return f.reject(new c.ConnectionError("WebSocket is closed"));default:var b=f.defer();return a.jsonrpc="2.0",a.id=this._nextRequestId(),this._pendingRequests[a.id]=b.resolver,this._webSocket.send(JSON.stringify(a)),this.emit("websocket:outgoingMessage",a),b.promise}},c.prototype._nextRequestId=function(){var a=-1;return function(){return a+=1}}(),c.prototype._handleMessage=function(a){try{var b=JSON.parse(a.data);b.hasOwnProperty("id")?this._handleResponse(b):b.hasOwnProperty("event")?this._handleEvent(b):this._console.warn("Unknown message type received. Message was: "+a.data)}catch(c){if(!(c instanceof SyntaxError))throw c;this._console.warn("WebSocket message parsing failed. Message was: "+a.data)}},c.prototype._handleResponse=function(a){if(!this._pendingRequests.hasOwnProperty(a.id))return void this._console.warn("Unexpected response received. Message was:",a);var b,d=this._pendingRequests[a.id];delete this._pendingRequests[a.id],a.hasOwnProperty("result")?d.resolve(a.result):a.hasOwnProperty("error")?(b=new c.ServerError(a.error.message),b.code=a.error.code,b.data=a.error.data,d.reject(b),this._console.warn("Server returned error:",a.error)):(b=new Error("Response without 'result' or 'error' received"),b.data={response:a},d.reject(b),this._console.warn("Response without 'result' or 'error' received. Message was:",a))},c.prototype._handleEvent=function(a){var b=a.event,c=a;delete c.event,this.emit("event:"+this._snakeToCamel(b),c)},c.prototype._getApiSpec=function(){return this._send({method:"core.describe"}).then(this._createApi.bind(this),this._handleWebSocketError).then(null,this._handleWebSocketError)},c.prototype._createApi=function(a){var b=function(a){return function(){var b=Array.prototype.slice.call(arguments);return this._send({method:a,params:b})}.bind(this)}.bind(this),c=function(a){var b=a.split(".");return b.length>=1&&"core"===b[0]&&(b=b.slice(1)),b},d=function(a){var b=this;return a.forEach(function(a){a=this._snakeToCamel(a),b[a]=b[a]||{},b=b[a]}.bind(this)),b}.bind(this),e=function(e){var f=c(e),g=this._snakeToCamel(f.slice(-1)[0]),h=d(f.slice(0,-1));h[g]=b(e),h[g].description=a[e].description,h[g].params=a[e].params}.bind(this);Object.keys(a).forEach(e),this.emit("state:online")},c.prototype._snakeToCamel=function(a){return a.replace(/(_[a-z])/g,function(a){return a.toUpperCase().replace("_","")})},b.exports=c},{"../lib/websocket/":1,bane:2,when:20}]},{},[21])(21)}); \ No newline at end of file