A suite to track Project Diva score statistics and ratings / D4DJ event data.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
projectdivar/server/node_modules/spex/lib/utils/index.js

95 lines
2.9 KiB

const npm = {
stat: require('./static')
};
module.exports = function ($p) {
const exp = {
formatError: npm.stat.formatError,
isPromise: npm.stat.isPromise,
isReadableStream: npm.stat.isReadableStream,
messageGap: npm.stat.messageGap,
extend: npm.stat.extend,
resolve: resolve,
wrap: wrap
};
return exp;
//////////////////////////////////////////
// Checks if the function is a generator,
// and if so - wraps it up into a promise;
function wrap(func) {
if (typeof func === 'function') {
if (func.constructor.name === 'GeneratorFunction') {
return asyncAdapter(func);
}
return func;
}
return null;
}
/////////////////////////////////////////////////////
// Resolves a mixed value into the actual value,
// consistent with the way mixed values are defined:
// https://github.com/vitaly-t/spex/wiki/Mixed-Values
function resolve(value, params, onSuccess, onError) {
const self = this;
let delayed = false;
function loop() {
while (typeof value === 'function') {
if (value.constructor.name === 'GeneratorFunction') {
value = asyncAdapter(value);
}
try {
value = params ? value.apply(self, params) : value.call(self);
} catch (e) {
onError(e, false); // false means 'threw an error'
return;
}
}
if (exp.isPromise(value)) {
value
.then(data => {
delayed = true;
value = data;
loop();
return null; // this dummy return is just to prevent Bluebird warnings;
})
.catch(error => {
onError(error, true); // true means 'rejected'
});
} else {
onSuccess(value, delayed);
}
}
loop();
}
// Generator-to-Promise adapter;
// Based on: https://www.promisejs.org/generators/#both
function asyncAdapter(generator) {
return function () {
const g = generator.apply(this, arguments);
function handle(result) {
if (result.done) {
return $p.resolve(result.value);
}
return $p.resolve(result.value)
.then(res => {
return handle(g.next(res));
}, err => {
return handle(g.throw(err));
});
}
return handle(g.next());
};
}
};