@ng-doc/builder
Version:
<!-- PROJECT LOGO --> <br /> <div align="center"> <a href="https://github.com/ng-doc/ng-doc"> <img src="https://ng-doc.com/assets/images/ng-doc.svg?raw=true" alt="Logo" height="150px"> </a>
54 lines • 2.87 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.factory = factory;
const core_1 = require("@ng-doc/core");
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const types_1 = require("../types");
const distinct_pending_1 = require("./distinct-pending");
const handle_cache_strategy_1 = require("./handle-cache-strategy");
const stack_1 = require("./stack");
let builderId = 0;
/**
* The factory function is a powerful tool for creating complex builders.
* It should be used when you need to build something based on the results of multiple other builders.
* @param tag - A string that identifies the builder.
* @param builders - An array of Observables of BuilderState.
* @param buildFn - A function that takes the results of the successful Observables and returns a Promise.
* @param cacheStrategy - An optional CacheStrategy object.
* @returns An Observable of BuilderState.
*/
function factory(tag, builders, buildFn, cacheStrategy) {
const id = builderId++;
return (0, rxjs_1.combineLatest)(builders).pipe((0, rxjs_1.switchMap)((states) => {
/**
* If any of the states are pending, return an Observable of BuilderPending.
*/
if (states.some(types_1.isBuilderPending)) {
return (0, rxjs_1.of)(new types_1.BuilderPending(tag));
}
const errors = states.filter(types_1.isBuilderError);
/**
* If there are any errors in the states, return an Observable of BuilderError.
*/
if (errors.length) {
return (0, rxjs_1.of)(new types_1.BuilderError(tag, (0, core_1.asArray)(...errors.map(({ error }) => error))));
}
/**
* If there are no errors or pending states, call the provided function with the results of the successful states.
* The result of the function is then mapped to a BuilderDone state.
*/
const buildFnResult = buildFn(...states.map(({ result }) => result));
/**
* We don't use ObservableInput here because it opens the door to passing an Observable
* as the result of the build function which might break the cache strategy, and final state.
*/
return (0, rxjs_1.from)(Promise.resolve(buildFnResult)).pipe((0, rxjs_1.map)((result) => new types_1.BuilderDone(tag, result)), (0, operators_1.catchError)((error) => (0, rxjs_1.of)(new types_1.BuilderError(tag, [error]))), (0, handle_cache_strategy_1.handleCacheStrategy)(`factory${id}`, cacheStrategy, states.every(({ fromCache }) => fromCache)));
}),
/**
* Prevents emitting the pending state twice in a row.
* This can happen if builders start working asynchronously based on some trigger.
*/
(0, distinct_pending_1.distinctPending)(), (0, stack_1.addToStack)(tag));
}
//# sourceMappingURL=factory.js.map
;