enricostara/telegram.link

View on GitHub
lib/utility.js

Summary

Maintainability
A
1 hr
Test Coverage
//     telegram.link
//     Copyright 2014 Enrico Stara 'enrico.stara@gmail.com'
//     Released under the MIT License
//     http://telegram.link

// The `Promise` polyfill.
require('es6-promise').polyfill();

// Calls a service and infers the arguments by the caller function.
function callService(service, emitter, channel, callback) {
    var argsValue = Array.prototype.slice.call(Array.prototype.slice.call(arguments)[4]);
    var callerFunc = arguments.callee.caller;
    var eventName = service.name || service._name;
    var callerArgNames = _retrieveArgumentNames(callerFunc);
    var props = {};
    for(var i = 0; i < callerArgNames.length - 1; i++) {
        props[callerArgNames[i]] = argsValue[i];
    }
    if (callback) {
        emitter.once(eventName, callback);
    }
    if (emitter.isReady(true)) {
        try {
            service({
                props: props,
                channel: channel,
                callback: createEventEmitterCallback(eventName, emitter)
            });
        } catch (err) {
            emitter.emit('error', err);
        }
    }
    return new Promise(function (fulfill, reject) {
        emitter.once('error', reject);
        emitter.once(eventName, function (result) {
            emitter.removeListener('error', reject);
            if (typeof result !== 'boolean' && result.instanceOf('mtproto.type.Rpc_error')) {
                reject(new Error(result.error_message));
            } else {
                fulfill(result);
            }
        });
    });
}
function _retrieveArgumentNames(func) {
    var found = /^[\s\(]*function[^(]*\(\s*([^)]*?)\s*\)/.exec(func.toString());
    return found && found[1] ? found[1].split(/,\s*/) : [];
}

// Provides a callback function that emits the supplied event type or an error event.
function createEventEmitterCallback(event, emitter) {
    return function (ex) {
        if (ex) {
            emitter.emit('error', ex);
        } else {
            var args = Array.prototype.slice.call(arguments);
            args[0] = event;
            emitter.emit.apply(emitter, args);
            if (event == 'end') {
                emitter.removeAllListeners();
            }
        }
    };
}

// Export the 'service' module.
exports.callService = callService;
exports.createEventEmitterCallback = createEventEmitterCallback;