UNPKG

@uirouter/core

Version:

UI-Router Core: Framework agnostic, State-based routing for JavaScript Single Page Apps

112 lines 5.15 kB
import { extend, identity } from '../common/common'; import { services } from '../common/coreservices'; import { trace } from '../common/trace'; import { stringify } from '../common/strings'; import { isFunction, isObject } from '../common/predicates'; import { isNullOrUndefined } from '../common/predicates'; // TODO: explicitly make this user configurable export var defaultResolvePolicy = { when: 'LAZY', async: 'WAIT', }; /** * The basic building block for the resolve system. * * Resolvables encapsulate a state's resolve's resolveFn, the resolveFn's declared dependencies, the wrapped (.promise), * and the unwrapped-when-complete (.data) result of the resolveFn. * * Resolvable.get() either retrieves the Resolvable's existing promise, or else invokes resolve() (which invokes the * resolveFn) and returns the resulting promise. * * Resolvable.get() and Resolvable.resolve() both execute within a context path, which is passed as the first * parameter to those fns. */ var Resolvable = /** @class */ (function () { function Resolvable(arg1, resolveFn, deps, policy, data) { this.resolved = false; this.promise = undefined; if (arg1 instanceof Resolvable) { extend(this, arg1); } else if (isFunction(resolveFn)) { if (isNullOrUndefined(arg1)) throw new Error('new Resolvable(): token argument is required'); if (!isFunction(resolveFn)) throw new Error('new Resolvable(): resolveFn argument must be a function'); this.token = arg1; this.policy = policy; this.resolveFn = resolveFn; this.deps = deps || []; this.data = data; this.resolved = data !== undefined; this.promise = this.resolved ? services.$q.when(this.data) : undefined; } else if (isObject(arg1) && arg1.token && (arg1.hasOwnProperty('resolveFn') || arg1.hasOwnProperty('data'))) { var literal = arg1; return new Resolvable(literal.token, literal.resolveFn, literal.deps, literal.policy, literal.data); } } Resolvable.prototype.getPolicy = function (state) { var thisPolicy = this.policy || {}; var statePolicy = (state && state.resolvePolicy) || {}; return { when: thisPolicy.when || statePolicy.when || defaultResolvePolicy.when, async: thisPolicy.async || statePolicy.async || defaultResolvePolicy.async, }; }; /** * Asynchronously resolve this Resolvable's data * * Given a ResolveContext that this Resolvable is found in: * Wait for this Resolvable's dependencies, then invoke this Resolvable's function * and update the Resolvable's state */ Resolvable.prototype.resolve = function (resolveContext, trans) { var _this = this; var $q = services.$q; // Gets all dependencies from ResolveContext and wait for them to be resolved var getResolvableDependencies = function () { return $q.all(resolveContext.getDependencies(_this).map(function (resolvable) { return resolvable.get(resolveContext, trans); })); }; // Invokes the resolve function passing the resolved dependencies as arguments var invokeResolveFn = function (resolvedDeps) { return _this.resolveFn.apply(null, resolvedDeps); }; var node = resolveContext.findNode(this); var state = node && node.state; var asyncPolicy = this.getPolicy(state).async; var customAsyncPolicy = isFunction(asyncPolicy) ? asyncPolicy : identity; // After the final value has been resolved, update the state of the Resolvable var applyResolvedValue = function (resolvedValue) { _this.data = resolvedValue; _this.resolved = true; _this.resolveFn = null; trace.traceResolvableResolved(_this, trans); return _this.data; }; // Sets the promise property first, then getsResolvableDependencies in the context of the promise chain. Always waits one tick. return (this.promise = $q .when() .then(getResolvableDependencies) .then(invokeResolveFn) .then(customAsyncPolicy) .then(applyResolvedValue)); }; /** * Gets a promise for this Resolvable's data. * * Fetches the data and returns a promise. * Returns the existing promise if it has already been fetched once. */ Resolvable.prototype.get = function (resolveContext, trans) { return this.promise || this.resolve(resolveContext, trans); }; Resolvable.prototype.toString = function () { return "Resolvable(token: " + stringify(this.token) + ", requires: [" + this.deps.map(stringify) + "])"; }; Resolvable.prototype.clone = function () { return new Resolvable(this); }; Resolvable.fromData = function (token, data) { return new Resolvable(token, function () { return data; }, null, null, data); }; return Resolvable; }()); export { Resolvable }; //# sourceMappingURL=resolvable.js.map