UNPKG

@mmuscat/angular-resource

Version:
237 lines (232 loc) 7.86 kB
import * as i0 from '@angular/core'; import { Injectable } from '@angular/core'; import { inject, use, select, subscribe, Service } from '@mmuscat/angular-composition-api'; import { tap, switchMap, materialize, takeUntil, repeat, filter, sample, exhaust } from 'rxjs/operators'; import { of, Subject, merge } from 'rxjs'; class Resource { constructor(value, error, pending, done) { this.value = value; this.error = error; this.pending = pending; this.done = done; } static createPending(value) { return new Resource(value, undefined, true, false); } static createNext(value) { return new Resource(value, undefined, false, false); } static createError(value, error) { return new Resource(value, error, false, true); } static createComplete(value) { return new Resource(value, undefined, false, true); } } class ResultObserver { constructor(value) { this.value = value; } next(value) { this.value.next(Resource.createNext(value)); } error(error) { this.value.next(Resource.createError(this.value.value.value, error)); } complete() { this.value.next(Resource.createComplete(this.value.value.value)); } } class PendingObserver { constructor(value) { this.value = value; } next() { this.value.next(Resource.createPending(this.value.value.value)); } } class Cache { constructor(factory, cache, unsubscribe) { this.factory = factory; this.cache = cache; this.unsubscribe = unsubscribe; } get(params, invalidate) { this.params = params; const { cache, factory } = this; const key = JSON.stringify(params); if (invalidate) { cache.delete(key); } if (cache.has(key)) { return of(cache.get(key)); } return factory(params).pipe(tap((value) => cache.set(key, value))); } clear() { this.cache.clear(); } invalidate() { return this.get(this.params, true); } subscribe() { return this; } } const globalCache = new Map(); class CacheFactory { get(token, queryFactory) { function unsubscribe() { var _a; (_a = globalCache.get(token)) === null || _a === void 0 ? void 0 : _a.delete(this); } const cache = new Cache(queryFactory, new Map(), unsubscribe); if (globalCache.has(token)) { globalCache.get(token).add(cache); return cache; } else { globalCache.set(token, new Set([cache])); return cache; } } } CacheFactory.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.4", ngImport: i0, type: CacheFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); CacheFactory.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.4", ngImport: i0, type: CacheFactory, providedIn: "root" }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.4", ngImport: i0, type: CacheFactory, decorators: [{ type: Injectable, args: [{ providedIn: "root" }] }] }); function queryFactory(factory, forwardRef, config) { const cacheFactory = inject(CacheFactory); const queryFunction = factory(); return function query(...params) { var _a; const args = params[params.length - 2]; const options = params[params.length - 1]; const value = use(Resource.createNext(options.initialValue)); const query = select({ next(valueOrCommand) { if (valueOrCommand instanceof Command) { switch (valueOrCommand.signal) { case CANCEL: cancel.next(); break; case INVALIDATE: if (valueOrCommand.params) { fetch(valueOrCommand.params, true); } else { cache.clear(); } break; default: throwInvalidCommand(); } } else { value(valueOrCommand); } }, value, }); const cache = cacheFactory.get(forwardRef(), queryFunction); const operator = (_a = config === null || config === void 0 ? void 0 : config.operator) !== null && _a !== void 0 ? _a : switchMap; const cancel = new Subject(); const fetch = use((args, invalidate) => [ args, invalidate, ]); const result = fetch.pipe(operator(([args, invalidate]) => cache.get(args, invalidate)), materialize(), takeUntil(cancel), repeat()); subscribe(cache); subscribe(fetch, new PendingObserver(value)); subscribe(result, new ResultObserver(value)); if (options.refetch) { const signal = merge(...options.refetch).pipe(filter((value) => (value instanceof Resource ? value.done : true))); subscribe(fetch.pipe(sample(signal)), (params) => fetch(params, true)); } if (args) { subscribe(merge(...(Array.isArray(args) ? args : [args])), fetch); } return query; }; } function createQueryFactory(factory, config) { const Query = new Service(queryFactory, { providedIn: "root", name: factory.name, arguments: [factory, () => Query, config], }); return Query; } const Query = createQueryFactory; const CANCEL = 0; const INVALIDATE = 1; class Command { constructor(signal, params) { this.signal = signal; this.params = params; } } function throwInvalidCommand() { throw new Error("Invalid command"); } function mutateFactory(factory, config) { var _a, _b; const operator = (_b = (_a = config === null || config === void 0 ? void 0 : config.operator) === null || _a === void 0 ? void 0 : _a.call(config)) !== null && _b !== void 0 ? _b : exhaust(); const queue = use(Function); const cancel = new Subject(); const result = queue.pipe(operator); const createStream = factory(); const value = use(Resource.createNext(undefined)); function mutate(params) { if (params instanceof Command) { switch (params.signal) { case CANCEL: return cancel.next(); default: throwInvalidCommand(); } } queue.next(createStream(params).pipe(materialize(), takeUntil(cancel))); } const mutation = select({ next: mutate, value, }); subscribe(queue, new PendingObserver(value)); subscribe(result, new ResultObserver(value)); return mutation; } function createMutationFactory(factory, config) { return new Service(mutateFactory, { providedIn: "root", name: factory.name, arguments: [factory, config], }); } const Mutation = createMutationFactory; function cancel(resource) { resource.next(new Command(CANCEL)); } function invalidate(query, params) { var _a; if (query.__ng_value) { query.next(new Command(INVALIDATE, params)); } else { const set = (_a = globalCache.get(query)) !== null && _a !== void 0 ? _a : []; for (const cache of set) { cache.clear(); cache.invalidate(); } } } /* * Public API Surface of resource */ /** * Generated bundle index. Do not edit. */ export { Mutation, Query, Resource, cancel, invalidate }; //# sourceMappingURL=mmuscat-angular-resource.js.map