File: /var/www/tana/frontend/node_modules/concurrently/node_modules/rx/src/core/linq/observable/spawn.js
var fnString = 'function',
throwString = 'throw',
isObject = Rx.internals.isObject;
function toThunk(obj, ctx) {
if (Array.isArray(obj)) { return objectToThunk.call(ctx, obj); }
if (isGeneratorFunction(obj)) { return observableSpawn(obj.call(ctx)); }
if (isGenerator(obj)) { return observableSpawn(obj); }
if (isObservable(obj)) { return observableToThunk(obj); }
if (isPromise(obj)) { return promiseToThunk(obj); }
if (typeof obj === fnString) { return obj; }
if (isObject(obj) || Array.isArray(obj)) { return objectToThunk.call(ctx, obj); }
return obj;
}
function objectToThunk(obj) {
var ctx = this;
return function (done) {
var keys = Object.keys(obj),
pending = keys.length,
results = new obj.constructor(),
finished;
if (!pending) {
timeoutScheduler.schedule(function () { done(null, results); });
return;
}
for (var i = 0, len = keys.length; i < len; i++) {
run(obj[keys[i]], keys[i]);
}
function run(fn, key) {
if (finished) { return; }
try {
fn = toThunk(fn, ctx);
if (typeof fn !== fnString) {
results[key] = fn;
return --pending || done(null, results);
}
fn.call(ctx, function(err, res) {
if (finished) { return; }
if (err) {
finished = true;
return done(err);
}
results[key] = res;
--pending || done(null, results);
});
} catch (e) {
finished = true;
done(e);
}
}
}
}
function observableToThunk(observable) {
return function (fn) {
var value, hasValue = false;
observable.subscribe(
function (v) {
value = v;
hasValue = true;
},
fn,
function () {
hasValue && fn(null, value);
});
}
}
function promiseToThunk(promise) {
return function(fn) {
promise.then(function(res) {
fn(null, res);
}, fn);
}
}
function isObservable(obj) {
return obj && typeof obj.subscribe === fnString;
}
function isGeneratorFunction(obj) {
return obj && obj.constructor && obj.constructor.name === 'GeneratorFunction';
}
function isGenerator(obj) {
return obj && typeof obj.next === fnString && typeof obj[throwString] === fnString;
}
/*
* Spawns a generator function which allows for Promises, Observable sequences, Arrays, Objects, Generators and functions.
* @param {Function} The spawning function.
* @returns {Function} a function which has a done continuation.
*/
var observableSpawn = Rx.spawn = function (fn) {
var isGenFun = isGeneratorFunction(fn);
return function (done) {
var ctx = this,
gen = fn;
if (isGenFun) {
var args = slice.call(arguments),
len = args.length,
hasCallback = len && typeof args[len - 1] === fnString;
done = hasCallback ? args.pop() : handleError;
gen = fn.apply(this, args);
} else {
done = done || handleError;
}
next();
function exit(err, res) {
timeoutScheduler.schedule(done.bind(ctx, err, res));
}
function next(err, res) {
var ret;
// multiple args
if (arguments.length > 2) {
res = slice.call(arguments, 1);
}
if (err) {
try {
ret = gen[throwString](err);
} catch (e) {
return exit(e);
}
}
if (!err) {
try {
ret = gen.next(res);
} catch (e) {
return exit(e);
}
}
if (ret.done) {
return exit(null, ret.value);
}
ret.value = toThunk(ret.value, ctx);
if (typeof ret.value === fnString) {
var called = false;
try {
ret.value.call(ctx, function() {
if (called) {
return;
}
called = true;
next.apply(ctx, arguments);
});
} catch (e) {
timeoutScheduler.schedule(function () {
if (called) {
return;
}
called = true;
next.call(ctx, e);
});
}
return;
}
// Not supported
next(new TypeError('Rx.spawn only supports a function, Promise, Observable, Object or Array.'));
}
}
};
function handleError(err) {
if (!err) { return; }
timeoutScheduler.schedule(function() {
throw err;
});
}