UNPKG

de

Version:

Simple asynchronous promise-based controller

202 lines (149 loc) 3.86 kB
'use strict'; var JSPromise; var hasProperty; JSPromise = /** @type JSPromise */ require('jspromise'); hasProperty = Object.prototype.hasOwnProperty; /** * @class Runtime * * @param {Provider} agent * @param {Object} [params] * */ function Runtime (agent, params) { var i; /** * @public * @memberOf {Runtime} * @property {Provider} * */ this.agent = agent; /** * @public * @memberOf {Runtime} * @property {Object} * */ this.params = {}; /** * @public * @memberOf {Runtime} * @property {Object} * */ for ( i in params ) { if ( hasProperty.call(params, i) ) { this.params[i] = params[i]; } } /** * @public * @memberOf {Runtime} * @property {Object} * */ this.promised = {}; } Runtime.prototype = { /** * @protected * @memberOf {Runtime} * @method * */ constructor: Runtime, /** * @public * @memberOf {Runtime} * @method * * @param {String} goal * * @returns {JSPromise} * */ invoke: function (goal) { var agent; var decl; var promise; var runtime; var start; // already invoked in current runtime if ( hasProperty.call(this.promised, goal) ) { return this.promised[goal]; } agent = this.agent; promise = agent.cache.get(goal); // agent cache if ( promise instanceof JSPromise ) { this.promised[goal] = promise; return promise; } decl = agent.decl(goal); runtime = this; start = Date.now(); promise = this.resolve(decl.deps).then(function (value) { var data; data = decl.data; if ( 'function' === typeof data ) { return data.apply(runtime, value.toArguments()); } return data; }); this.promised[goal] = promise; // set agent cache agent.cache.set(goal, promise, decl); promise.always(function (promise) { agent.emit(['accept', 'reject'][ +promise.isRejected() ], { path: goal, time: Date.now() - start, data: promise.valueOf() }); }).done(); return promise; }, /** * @public * @memberOf {Runtime} * @method * * @param {String|Array<String>} goals * * @returns {JSPromise} * */ resolve: function (goals) { var agent; var i; var l; var promises; agent = this.agent; if ( !Array.isArray(goals) ) { if ( null === goals || void 0 === goals ) { goals = []; } else { goals = [goals]; } } promises = {}; for ( i = 0, l = goals.length; i < l; i += 1 ) { promises[goals[i]] = this.invoke(goals[i]); } return JSPromise.allResolved(promises).then(function (promises) { var bundle; var data; var goal; var promise; bundle = agent.createBundle(); for ( goal in promises ) { /*jshint forin: false*/ if ( !hasProperty.call(promises, goal) ) { continue; } promise = promises[goal]; data = promise.valueOf(); goal = agent.getPath(goal); if ( promise.isRejected() ) { bundle.setError(goal, data); continue; } bundle.setResult(goal, data); } return bundle; }); } }; module.exports = Runtime;