@ortoo/angular-resource
Version:
Magical CRUD resource management for angular
113 lines • 15.2 kB
JavaScript
// tslint:disable variable-name only-arrow-functions
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromPromise';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/first';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/skip';
import 'rxjs/add/operator/toPromise';
import { ArrayEmitter } from './array-emitter';
import { Chain } from './chain';
import { isEqual } from 'lodash';
import { isString } from 'lodash';
import { throttle } from 'lodash';
// Recursively follows a property that links to the same model.
// For now rather obtusively just redraw from the seeds when anything changes.
export function CollectionFactory() {
let _collections = [];
class Collection extends ArrayEmitter {
constructor(Resource, seeds, searcher) {
super();
let nodes = this;
let watchers = [];
let collecting = false;
let recollect = false;
_collections.push(nodes);
let resolve;
nodes.$promise = new Promise(_resolve => resolve = _resolve);
nodes.$resolved = false;
nodes.chain = chain;
nodes.update = update;
function chain(Model, qryFn) {
return Chain(nodes, Model, qryFn);
}
function clear() {
nodes.length = 0;
watchers.forEach(sub => sub.unsubscribe());
}
function runCollection() {
if (!collecting) {
recollect = false;
collecting = true;
clear();
collectRecursive(seeds).then(function () {
collecting = false;
if (recollect) {
runCollection();
}
else {
// Notify that we've updated and settled
nodes.$emitter.emit('update', nodes);
if (!nodes.$resolved) {
nodes.$resolved = true;
resolve(nodes);
}
}
});
}
else {
// We're running - rerun once we are done
recollect = true;
}
}
function collectRecursive(start) {
let starters;
if (Array.isArray(start)) {
starters = start;
}
else {
starters = [start];
}
let unseen = starters.filter(model => nodes.indexOf(model) === -1);
if (unseen.length === 0) {
return Promise.resolve();
}
for (let model of unseen) {
nodes.push(model);
}
let searcherObs = searcher(unseen);
// Check for changes and rerun collection (the first is just the
// initial value)
let watcher = searcherObs.distinctUntilChanged((newVal, oldVal) => {
return isEqual(oldVal, newVal);
}).skip(1).subscribe(() => {
runCollection();
});
watchers.push(watcher);
return searcherObs.mergeMap(function (result) {
// Result could either be an array of ids, or the objects themselves
if (result && isString(result[0])) {
// Ids
return Observable.fromPromise(Resource.get(result).$promise);
}
else {
return Observable.of(result);
}
}).first().toPromise().then(function (results) {
return collectRecursive(results);
});
}
function update() {
runCollection();
}
// Do an initial collection run
runCollection();
}
}
Collection.check = throttle(() => {
_collections.forEach(coll => coll.check());
}, 100);
return Collection;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIvQG9ydG9vL2FuZ3VsYXItcmVzb3VyY2UvIiwic291cmNlcyI6WyJjb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG9EQUFvRDtBQUNwRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHN0MsT0FBTyxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sd0NBQXdDLENBQUM7QUFDaEQsT0FBTyx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLDRCQUE0QixDQUFDO0FBQ3BDLE9BQU8sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyw2QkFBNkIsQ0FBQztBQUVyQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUVoQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDbEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQVdsQywrREFBK0Q7QUFDL0QsOEVBQThFO0FBQzlFLE1BQU07SUFDSixJQUFJLFlBQVksR0FBaUIsRUFBRSxDQUFDO0lBRXBDLGdCQUFpQixTQUFRLFlBQW1CO1FBYTFDLFlBQVksUUFBeUIsRUFBRSxLQUFvQixFQUFFLFFBQTRCO1lBQ3ZGLEtBQUssRUFBRSxDQUFDO1lBRVIsSUFBSSxLQUFLLEdBQWUsSUFBSSxDQUFDO1lBQzdCLElBQUksUUFBUSxHQUFtQixFQUFFLENBQUM7WUFDbEMsSUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDO1lBQ3ZCLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQztZQUV0QixZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXpCLElBQUksT0FBaUIsQ0FBQztZQUN0QixLQUFL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ZnVuY3Rpb25zXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcy9PYnNlcnZhYmxlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMvU3Vic2NyaXB0aW9uJztcblxuaW1wb3J0ICdyeGpzL2FkZC9vYnNlcnZhYmxlL2Zyb21Qcm9taXNlJztcbmltcG9ydCAncnhqcy9hZGQvb2JzZXJ2YWJsZS9vZic7XG5pbXBvcnQgJ3J4anMvYWRkL29wZXJhdG9yL2Rpc3RpbmN0VW50aWxDaGFuZ2VkJztcbmltcG9ydCAncnhqcy9hZGQvb3BlcmF0b3IvZmlyc3QnO1xuaW1wb3J0ICdyeGpzL2FkZC9vcGVyYXRvci9tZXJnZU1hcCc7XG5pbXBvcnQgJ3J4anMvYWRkL29wZXJhdG9yL3NraXAnO1xuaW1wb3J0ICdyeGpzL2FkZC9vcGVyYXRvci90b1Byb21pc2UnO1xuXG5pbXBvcnQgeyBBcnJheUVtaXR0ZXIgfSBmcm9tICcuL2FycmF5LWVtaXR0ZXInO1xuaW1wb3J0IHsgQ2hhaW4gfSBmcm9tICcuL2NoYWluJztcblxuaW1wb3J0IHsgaXNFcXVhbCB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBpc1N0cmluZyB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyB0aHJvdHRsZSB9IGZyb20gJ2xvZGFzaCc7XG5cbmltcG9ydCB7IENvbGxlY3Rpb24gYXMgSUNvbGxlY3Rpb24sXG4gICAgICAgICBDb2xsZWN0aW9uU2VhcmNoZXIsXG4gICAgICAgICBDb2xsZWN0aW9uU3RhdGljLFxuICAgICAgICAgTW9kZWwsXG4gICAgICAgICBRdWVyeSxcbiAgICAgICAgIFF1ZXJ5RnVuY3Rpb24sXG4gICAgICAgICBSZXNvdXJjZSxcbiAgICAgICAgIFNlZWRzIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8vIFJlY3Vyc2l2ZWx5IGZvbGxvd3MgYSBwcm9wZXJ0eSB0aGF0IGxpbmtzIHRvIHRoZSBzYW1lIG1vZGVsLlxuLy8gRm9yIG5vdyByYXRoZXIgb2J0dXNpdmVseSBqdXN0IHJlZHJhdyBmcm9tIHRoZSBzZWVkcyB3aGVuIGFueXRoaW5nIGNoYW5nZXMuXG5leHBvcnQgZnVuY3Rpb24gQ29sbGVjdGlvbkZhY3RvcnkoKSB7XG4gIGxldCBfY29sbGVjdGlvbnM6IENvbGxlY3Rpb25bXSA9IFtdO1xuXG4gIGNsYXNzIENvbGxlY3Rpb24gZXh0ZW5kcyBBcnJheUVtaXR0ZXI8TW9kZWw+IGltcGxlbWVudHMgSUNvbGxlY3Rpb248TW9kZWw+IHtcblxuICAgIHB1YmxpYyBzdGF0aWMgY2hlY2sgPSB0aHJvdHRsZSgoKSA9PiB7XG4gICAgICBfY29sbGVjdGlvbnMuZm9yRWFjaChjb2xsID0+IGNvbGwuY2hlY2soKSk7XG4gICAgfSwgMTAwKTtcblxuICAgIHB1YmxpYyAkcHJvbWlzZTogUHJvbWlzZTxJQ29sbGVjdGlvbjxNb2RlbD4+O1xuICAgIHB1YmxpYyAkcmVzb2x2ZWQ6IGJvb2xlYW47XG5cbiAgICBwdWJsaWMgY2hhaW46IHsoTW9kZWw6IGFueSwgcXJ5Rm46IFF1ZXJ5RnVuY3Rpb24pOiBRdWVyeTxNb2RlbD59O1xuICAgIHB1YmxpYyB1cGRhdGU6IHsoKTogdm9pZH07XG4gICAgcHVibGljIGNoZWNrOiB7KCk6IHZvaWR9O1xuXG4gICAgY29uc3RydWN0b3IoUmVzb3VyY2U6IFJlc291cmNlPE1vZGVsPiwgc2VlZHM6IE1vZGVsIHwgU2VlZHMsIHNlYXJjaGVyOiBDb2xsZWN0aW9uU2VhcmNoZXIpIHtcbiAgICAgIHN1cGVyKCk7XG5cbiAgICAgIGxldCBub2RlczogQ29sbGVjdGlvbiA9IHRoaXM7XG4gICAgICBsZXQgd2F0Y2hlcnM6IFN1YnNjcmlwdGlvbltdID0gW107XG4gICAgICBsZXQgY29sbGVjdGluZyA9IGZhbHNlO1xuICAgICAgbGV0IHJlY29sbGVjdCA9IGZhbHNlO1xuXG4gICAgICBfY29sbGVjdGlvbnMucHVzaChub2Rlcyk7XG5cbiAgICAgIGxldCByZXNvbHZlOiBGdW5jdGlvbjtcbiAgICAgIG5vZGVzLiRwcm9taXNlID0gbmV3IFByb21pc2UoX3Jlc29sdmUgPT4gcmVzb2x2ZSA9IF9yZXNvbHZlKTtcbiAgICAgIG5vZGVzLiRyZXNvbHZlZCA9IGZhbHNlO1xuICAgICAgbm9kZXMuY2hhaW4gPSBjaGFpbjtcbiAgICAgIG5vZGVzLnVwZGF0ZSA9IHVwZGF0ZTtcblxuICAgICAgZnVuY3Rpb24gY2hhaW4oTW9kZWw6IFJlc291cmNlPE1vZGVsPiwgcXJ5Rm46IFF1ZXJ5RnVuY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIENoYWluKG5vZGVzLCBNb2RlbCwgcXJ5Rm4pO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBjbGVhcigpIHtcbiAgICAgICAgbm9kZXMubGVuZ3RoID0gMDtcbiAgICAgICAgd2F0Y2hlcnMuZm9yRWFjaChzdWIgPT4gc3ViLnVuc3Vic2NyaWJlKCkpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBydW5Db2xsZWN0aW9uKCkge1xuICAgICAgICBpZiAoIWNvbGxlY3RpbmcpIHtcbiAgICAgICAgICByZWNvbGxlY3QgPSBmYWxzZTtcbiAgICAgICAgICBjb2xsZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgICBjbGVhcigpO1xuICAgICAgICAgIGNvbGxlY3RSZWN1cnNpdmUoc2VlZHMpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb2xsZWN0aW5nID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmIChyZWNvbGxlY3QpIHtcbiAgICAgICAgICAgICAgcnVuQ29sbGVjdGlvbigpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gTm90aWZ5IHRoYXQgd2UndmUgdXBkYXRlZCBhbmQgc2V0dGxlZFxuICAgICAgICAgICAgICBub2Rlcy4kZW1pdHRlci5lbWl0KCd1cGRhdGUnLCBub2Rlcyk7XG5cbiAgICAgICAgICAgICAgaWYgKCFub2Rlcy4kcmVzb2x2ZWQpIHtcbiAgICAgICAgICAgICAgICBub2Rlcy4kcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJlc29sdmUobm9kZXMpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gV2UncmUgcnVubmluZyAtIHJlcnVuIG9uY2Ugd2UgYXJlIGRvbmVcbiAgICAgICAgICByZWNvbGxlY3QgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGNvbGxlY3RSZWN1cnNpdmUoc3RhcnQ6IChNb2RlbCB8IE1vZGVsW10pKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCBzdGFydGVyczogTW9kZWxbXTtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoc3RhcnQpKSB7XG4gICAgICAgICAgc3RhcnRlcnMgPSBzdGFydCBhcyBNb2RlbFtdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXJ0ZXJzID0gW3N0YXJ0IGFzIE1vZGVsXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCB1bnNlZW4gPSBzdGFydGVycy5maWx0ZXIobW9kZWwgPT4gbm9kZXMuaW5kZXhPZihtb2RlbCkgPT09IC0xKTtcblxuICAgICAgICBpZiAodW5zZWVuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IG1vZGVsIG9mIHVuc2Vlbikge1xuICAgICAgICAgIG5vZGVzLnB1c2gobW9kZWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHNlYXJjaGVyT2JzID0gc2VhcmNoZXIodW5zZWVuKTtcblxuICAgICAgICAvLyBDaGVjayBmb3IgY2hhbmdlcyBhbmQgcmVydW4gY29sbGVjdGlvbiAodGhlIGZpcnN0IGlzIGp1c3QgdGhlXG4gICAgICAgIC8vIGluaXRpYWwgdmFsdWUpXG4gICAgICAgIGxldCB3YXRjaGVyID0gc2VhcmNoZXJPYnMuZGlzdGluY3RVbnRpbENoYW5nZWQoKG5ld1ZhbCwgb2xkVmFsKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGlzRXF1YWwob2xkVmFsLCBuZXdWYWwpO1xuICAgICAgICB9KS5za2lwKDEpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgcnVuQ29sbGVjdGlvbigpO1xuICAgICAgICB9KTtcblxuICAgICAgICB3YXRjaGVycy5wdXNoKHdhdGNoZXIpO1xuXG4gICAgICAgIHJldHVybiBzZWFyY2hlck9icy5tZXJnZU1hcChmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgLy8gUmVzdWx0IGNvdWxkIGVpdGhlciBiZSBhbiBhcnJheSBvZiBpZHMsIG9yIHRoZSBvYmplY3RzIHRoZW1zZWx2ZXNcbiAgICAgICAgICBpZiAocmVzdWx0ICYmIGlzU3RyaW5nKHJlc3VsdFswXSkpIHtcbiAgICAgICAgICAgIC8vIElkc1xuICAgICAgICAgICAgcmV0dXJuIE9ic2VydmFibGUuZnJvbVByb21pc2UoUmVzb3VyY2UuZ2V0KHJlc3VsdCBhcyBzdHJpbmdbXSkuJHByb21pc2UgYXMgUHJvbWlzZTxNb2RlbFtdPik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBPYnNlcnZhYmxlLm9mKHJlc3VsdCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KS5maXJzdCgpLnRvUHJvbWlzZSgpLnRoZW4oZnVuY3Rpb24ocmVzdWx0czogU2VlZHMpIHtcbiAgICAgICAgICByZXR1cm4gY29sbGVjdFJlY3Vyc2l2ZShyZXN1bHRzKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHVwZGF0ZSgpIHtcbiAgICAgICAgcnVuQ29sbGVjdGlvbigpO1xuICAgICAgfVxuXG4gICAgICAvLyBEbyBhbiBpbml0aWFsIGNvbGxlY3Rpb24gcnVuXG4gICAgICBydW5Db2xsZWN0aW9uKCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIENvbGxlY3Rpb24gYXMgQ29sbGVjdGlvblN0YXRpYzxNb2RlbD47XG59XG4iXX0=