UNPKG

@obliczeniowo/elementary

Version:
233 lines (226 loc) 9.32 kB
import * as i1 from '@angular/common/http'; import { HttpResponse, HttpResponseBase, HttpErrorResponse } from '@angular/common/http'; import * as i0 from '@angular/core'; import { Injectable } from '@angular/core'; import { Subject, of, filter, map, tap, finalize } from 'rxjs'; class CacheModel { options; constructor(options) { this.options = options; } } class CacheService { cache = new Map(); /** * triggered when cache name value is changed or removed, not triggered when all cache was cleared */ changed = new Subject(); /** * triggered when one name of cache was cleared (emit string as name of removed one) or all was cleared (emit undefined) */ cleared = new Subject(); set(name, item) { this.cache.set(name, item); this.changed.next({ name, item }); } get(name) { return this.cache.get(name); } has(name) { return this.cache.has(name); } /** * when no name clear all, single one when name is known */ clear(name) { if (name) { this.cache.delete(name); this.changed.next({ name }); this.cleared.next(name); } else { this.cache.clear(); this.cleared.next(undefined); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: CacheService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: CacheService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: CacheService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); class HttpCacheService { http; constructor(http) { this.http = http; } request(method, url, options) { if (options?.cache?.name) { options.cache = { ...options.cache, name: `${method.toLowerCase()}:${options?.cache?.name}` }; } return this.http.request(method, url, { ...options, body: options?.cache ? new CacheModel({ ...options.cache, data: options?.body }) : options?.body }); } get(url, options) { return this.request('GET', url, options); } patch(url, body, options) { options = { ...options, body }; return this.request('PATCH', url, options); } post(url, body, options) { options = { ...options, body }; return this.request('POST', url, options); } put(url, body, options) { options = { ...options, body }; return this.request('PUT', url, options); } delete(url, options) { return this.request('DELETE', url, options); } retrigger(cacheItem) { if (cacheItem?.cache) { this.request(cacheItem.method, cacheItem.fullPath, { cache: { ...cacheItem.cache, name: cacheItem.cache?.name && cacheItem.cache?.name.split(':')[1], type: 'reload' } }).subscribe(); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: HttpCacheService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: HttpCacheService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: HttpCacheService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.HttpClient }] }); class CacheInterceptorService { cache; http; constructor(cache, http) { this.cache = cache; this.http = http; } intercept(request, next) { const body = request.body; const hasCacheModel = body instanceof CacheModel; if (hasCacheModel && body?.options?.type === 'reload' && body?.options?.name) { this.cache.clear(body.options?.name); } if (hasCacheModel && body.options?.type !== 'collect') { if (body?.options?.name) { if (this.cache.has(body?.options?.name)) { const data = this.cache.get(body?.options?.name); if (data.reloading || body?.options?.reloadOn && !body?.options?.reloadOn(data) || !body?.options?.reloadOn) { return of(new HttpResponse({ body: body?.options?.withCacheItem && data || data?.body, status: 304 })); } data.reloading = true; } } request = request.clone({ body: body?.options?.data }); } const triggeredAt = new Date(); const setCacheState = (reloading) => { if (hasCacheModel && body?.options?.name && this.cache.has(body?.options?.name)) { const cacheItem = this.cache.get(body?.options?.name); cacheItem.reloading = reloading; if (reloading) { cacheItem.external = body.options.external; cacheItem.responseAt = new Date(); cacheItem.reqBody = request.body; cacheItem.cache = body.options; } } }; return next.handle(request).pipe(filter(resp => resp instanceof HttpResponseBase), map((resp) => { if (hasCacheModel && resp?.body) { resp.body = body?.options?.convert?.(resp.body) || resp.body; } return resp; }), map((resp) => { if (!hasCacheModel || body?.options?.type !== 'collect') { return resp; } const cache = body?.options?.name && this.cache.has(body?.options?.name) && this.cache.get(body?.options?.name) || { body: [], triggeredAt, fullPath: request.urlWithParams, method: request.method.toLowerCase() }; if (resp.body) { cache.body.push(resp.body); cache.triggeredAt = new Date(); cache.method = request.method.toLowerCase(); } if (body?.options?.maxSize && cache.body.length > body.options.maxSize) { cache.body.shift(); } if (body?.options?.name) { this.cache.set(body?.options?.name, cache); } resp.body = cache.body; return resp; }), map((resp) => { if (hasCacheModel && resp?.body && body?.options?.name) { if (body.options?.type !== 'collect') { this.cache.set(body?.options?.name, { body: resp.body, triggeredAt, fullPath: request.urlWithParams, method: request.method.toLowerCase() }); } } setCacheState(true); if (hasCacheModel && body.options?.withCacheItem) { if (!body?.options?.name) { throw new HttpErrorResponse({ status: 404, statusText: 'For withCacheItem=true option cache name is required!' }); } resp.body = { ...this.cache.get(body?.options?.name) }; delete resp.body.reloading; } return resp; }), tap(() => { if (hasCacheModel) { if (body?.options?.clear) { body.options.clear.forEach(clear => this.cache.clear(clear)); } if (body?.options?.retrigger) { body.options.retrigger.forEach((retrigger) => this.http.retrigger(this.cache.get(retrigger))); } } }), finalize(() => { setCacheState(); })); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: CacheInterceptorService, deps: [{ token: CacheService }, { token: HttpCacheService }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: CacheInterceptorService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: CacheInterceptorService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: CacheService }, { type: HttpCacheService }] }); /** * Generated bundle index. Do not edit. */ export { CacheInterceptorService, CacheModel, CacheService, HttpCacheService }; //# sourceMappingURL=obliczeniowo-elementary-http-cache.mjs.map