ng-http-caching 2.0.1 → 13.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,65 +0,0 @@
1
- import { HttpResponse } from '@angular/common/http';
2
- import { Injectable } from '@angular/core';
3
- import { of } from 'rxjs';
4
- import { tap, finalize, share } from 'rxjs/operators';
5
- import { NgHttpCachingHeaders } from './ng-http-caching.service';
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "./ng-http-caching.service";
8
- export class NgHttpCachingInterceptorService {
9
- constructor(cacheService) {
10
- this.cacheService = cacheService;
11
- }
12
- intercept(req, next) {
13
- // run garbage collector
14
- this.cacheService.runGc();
15
- // Don't cache if it's not cacheable
16
- if (!this.cacheService.isCacheable(req)) {
17
- return this.sendRequest(req, next);
18
- }
19
- // Checked if there is pending response for this request
20
- const cachedObservable = this.cacheService.getFromQueue(req);
21
- if (cachedObservable) {
22
- // console.log('cachedObservable', req);
23
- return cachedObservable;
24
- }
25
- // Checked if there is cached response for this request
26
- const cachedResponse = this.cacheService.getFromCache(req);
27
- if (cachedResponse) {
28
- // console.log('cachedResponse', req);
29
- return of(cachedResponse.clone());
30
- }
31
- // If the request of going through for first time
32
- // then let the request proceed and cache the response
33
- // console.log('sendRequest', req);
34
- const shared = this.sendRequest(req, next).pipe(tap(event => {
35
- if (event instanceof HttpResponse) {
36
- this.cacheService.addToCache(req, event.clone());
37
- }
38
- }), finalize(() => {
39
- // delete pending request
40
- this.cacheService.deleteFromQueue(req);
41
- }), share());
42
- // add pending request to queue for cache parallell request
43
- this.cacheService.addToQueue(req, shared);
44
- return shared;
45
- }
46
- /**
47
- * Send http request (next handler)
48
- */
49
- sendRequest(req, next) {
50
- let cloned = req.clone();
51
- // trim custom headers before send request
52
- Object.values(NgHttpCachingHeaders).forEach(ngHttpCachingHeaders => {
53
- if (cloned.headers.has(ngHttpCachingHeaders)) {
54
- cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });
55
- }
56
- });
57
- return next.handle(cloned);
58
- }
59
- }
60
- NgHttpCachingInterceptorService.ɵfac = function NgHttpCachingInterceptorService_Factory(t) { return new (t || NgHttpCachingInterceptorService)(i0.ɵɵinject(i1.NgHttpCachingService)); };
61
- NgHttpCachingInterceptorService.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: NgHttpCachingInterceptorService, factory: NgHttpCachingInterceptorService.ɵfac });
62
- (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NgHttpCachingInterceptorService, [{
63
- type: Injectable
64
- }], function () { return [{ type: i1.NgHttpCachingService }]; }, null); })();
65
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctaHR0cC1jYWNoaW5nLWludGVyY2VwdG9yLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1odHRwLWNhY2hpbmcvc3JjL2xpYi9uZy1odHRwLWNhY2hpbmctaW50ZXJjZXB0b3Iuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXdELFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzFHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0QyxPQUFPLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RCxPQUFPLEVBQXdCLG9CQUFvQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7OztBQUl2RixNQUFNLE9BQU8sK0JBQStCO0lBRTFDLFlBQTZCLFlBQWtDO1FBQWxDLGlCQUFZLEdBQVosWUFBWSxDQUFzQjtJQUFHLENBQUM7SUFFbkUsU0FBUyxDQUFDLEdBQXFCLEVBQUUsSUFBaUI7UUFDaEQsd0JBQXdCO1FBQ3hCLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFMUIsb0NBQW9DO1FBQ3BDLElBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRztZQUN6QyxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1NBQ3BDO1FBRUQsd0RBQXdEO1FBQ3hELE1BQU0sZ0JBQWdCLEdBQStCLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pGLElBQUssZ0JBQWdCLEVBQUc7WUFDdEIsd0NBQXdDO1lBQ3hDLE9BQU8sZ0JBQWdCLENBQUM7U0FDekI7UUFFRCx1REFBdUQ7UUFDdkQsTUFBTSxjQUFjLEdBQXNCLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzlFLElBQUksY0FBYyxFQUFFO1lBQ2xCLHNDQUFzQztZQUN0QyxPQUFPLEVBQUUsQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztTQUNuQztRQUVELGlEQUFpRDtRQUNqRCxzREFBc0Q7UUFDdEQsbUNBQW1DO1FBQ25DLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FDN0MsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ1YsSUFBSSxLQUFLLFlBQVksWUFBWSxFQUFFO2dCQUNqQyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7YUFDbEQ7UUFDSCxDQUFDLENBQUMsRUFDRixRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ1oseUJBQXlCO1lBQ3pCLElBQUksQ0FBQyxZQUFZLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxFQUNGLEtBQUssRUFBRSxDQUNSLENBQUM7UUFFRiwyREFBMkQ7UUFDM0QsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRTFDLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7T0FFRztJQUNILFdBQVcsQ0FBQyxHQUFxQixFQUFFLElBQWlCO1FBQ2xELElBQUksTUFBTSxHQUFxQixHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDM0MsMENBQTBDO1FBQzFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsRUFBRTtZQUNqRSxJQUFLLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLEVBQUc7Z0JBQzlDLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ2pGO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDN0IsQ0FBQzs7OEdBN0RVLCtCQUErQjtxRkFBL0IsK0JBQStCLFdBQS9CLCtCQUErQjt1RkFBL0IsK0JBQStCO2NBRDNDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwRXZlbnQsIEh0dHBIYW5kbGVyLCBIdHRwSW50ZXJjZXB0b3IsIEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFwLCBmaW5hbGl6ZSwgc2hhcmUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBOZ0h0dHBDYWNoaW5nU2VydmljZSwgTmdIdHRwQ2FjaGluZ0hlYWRlcnMgfSBmcm9tICcuL25nLWh0dHAtY2FjaGluZy5zZXJ2aWNlJztcblxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTmdIdHRwQ2FjaGluZ0ludGVyY2VwdG9yU2VydmljZSBpbXBsZW1lbnRzIEh0dHBJbnRlcmNlcHRvciB7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBjYWNoZVNlcnZpY2U6IE5nSHR0cENhY2hpbmdTZXJ2aWNlKSB7fVxuXG4gIGludGVyY2VwdChyZXE6IEh0dHBSZXF1ZXN0PGFueT4sIG5leHQ6IEh0dHBIYW5kbGVyKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4ge1xuICAgIC8vIHJ1biBnYXJiYWdlIGNvbGxlY3RvclxuICAgIHRoaXMuY2FjaGVTZXJ2aWNlLnJ1bkdjKCk7XG5cbiAgICAvLyBEb24ndCBjYWNoZSBpZiBpdCdzIG5vdCBjYWNoZWFibGVcbiAgICBpZiAoICF0aGlzLmNhY2hlU2VydmljZS5pc0NhY2hlYWJsZShyZXEpICkge1xuICAgICAgcmV0dXJuIHRoaXMuc2VuZFJlcXVlc3QocmVxLCBuZXh0KTtcbiAgICB9XG5cbiAgICAvLyBDaGVja2VkIGlmIHRoZXJlIGlzIHBlbmRpbmcgcmVzcG9uc2UgZm9yIHRoaXMgcmVxdWVzdFxuICAgIGNvbnN0IGNhY2hlZE9ic2VydmFibGU6IE9ic2VydmFibGU8SHR0cEV2ZW50PGFueT4+ID0gdGhpcy5jYWNoZVNlcnZpY2UuZ2V0RnJvbVF1ZXVlKHJlcSk7XG4gICAgaWYgKCBjYWNoZWRPYnNlcnZhYmxlICkge1xuICAgICAgLy8gY29uc29sZS5sb2coJ2NhY2hlZE9ic2VydmFibGUnLCByZXEpO1xuICAgICAgcmV0dXJuIGNhY2hlZE9ic2VydmFibGU7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2tlZCBpZiB0aGVyZSBpcyBjYWNoZWQgcmVzcG9uc2UgZm9yIHRoaXMgcmVxdWVzdFxuICAgIGNvbnN0IGNhY2hlZFJlc3BvbnNlOiBIdHRwUmVzcG9uc2U8YW55PiA9IHRoaXMuY2FjaGVTZXJ2aWNlLmdldEZyb21DYWNoZShyZXEpO1xuICAgIGlmIChjYWNoZWRSZXNwb25zZSkge1xuICAgICAgLy8gY29uc29sZS5sb2coJ2NhY2hlZFJlc3BvbnNlJywgcmVxKTtcbiAgICAgIHJldHVybiBvZihjYWNoZWRSZXNwb25zZS5jbG9uZSgpKTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgcmVxdWVzdCBvZiBnb2luZyB0aHJvdWdoIGZvciBmaXJzdCB0aW1lXG4gICAgLy8gdGhlbiBsZXQgdGhlIHJlcXVlc3QgcHJvY2VlZCBhbmQgY2FjaGUgdGhlIHJlc3BvbnNlXG4gICAgLy8gY29uc29sZS5sb2coJ3NlbmRSZXF1ZXN0JywgcmVxKTtcbiAgICBjb25zdCBzaGFyZWQgPSB0aGlzLnNlbmRSZXF1ZXN0KHJlcSwgbmV4dCkucGlwZShcbiAgICAgIHRhcChldmVudCA9PiB7XG4gICAgICAgIGlmIChldmVudCBpbnN0YW5jZW9mIEh0dHBSZXNwb25zZSkge1xuICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlLmFkZFRvQ2FjaGUocmVxLCBldmVudC5jbG9uZSgpKTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgIC8vIGRlbGV0ZSBwZW5kaW5nIHJlcXVlc3RcbiAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2UuZGVsZXRlRnJvbVF1ZXVlKHJlcSk7XG4gICAgICB9KSxcbiAgICAgIHNoYXJlKClcbiAgICApO1xuXG4gICAgLy8gYWRkIHBlbmRpbmcgcmVxdWVzdCB0byBxdWV1ZSBmb3IgY2FjaGUgcGFyYWxsZWxsIHJlcXVlc3RcbiAgICB0aGlzLmNhY2hlU2VydmljZS5hZGRUb1F1ZXVlKHJlcSwgc2hhcmVkKTtcblxuICAgIHJldHVybiBzaGFyZWQ7XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBodHRwIHJlcXVlc3QgKG5leHQgaGFuZGxlcilcbiAgICovXG4gIHNlbmRSZXF1ZXN0KHJlcTogSHR0cFJlcXVlc3Q8YW55PiwgbmV4dDogSHR0cEhhbmRsZXIpOiBPYnNlcnZhYmxlPEh0dHBFdmVudDxhbnk+PiB7XG4gICAgbGV0IGNsb25lZDogSHR0cFJlcXVlc3Q8YW55PiA9IHJlcS5jbG9uZSgpO1xuICAgIC8vIHRyaW0gY3VzdG9tIGhlYWRlcnMgYmVmb3JlIHNlbmQgcmVxdWVzdFxuICAgIE9iamVjdC52YWx1ZXMoTmdIdHRwQ2FjaGluZ0hlYWRlcnMpLmZvckVhY2gobmdIdHRwQ2FjaGluZ0hlYWRlcnMgPT4ge1xuICAgICAgaWYgKCBjbG9uZWQuaGVhZGVycy5oYXMobmdIdHRwQ2FjaGluZ0hlYWRlcnMpICkge1xuICAgICAgICBjbG9uZWQgPSBjbG9uZWQuY2xvbmUoeyBoZWFkZXJzOiBjbG9uZWQuaGVhZGVycy5kZWxldGUobmdIdHRwQ2FjaGluZ0hlYWRlcnMpIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBuZXh0LmhhbmRsZShjbG9uZWQpO1xuICB9XG59XG4iXX0=
@@ -1,45 +0,0 @@
1
- import { NgModule } from '@angular/core';
2
- import { HTTP_INTERCEPTORS } from '@angular/common/http';
3
- import { NG_HTTP_CACHING_CONFIG, NgHttpCachingService, } from './ng-http-caching.service';
4
- import { NgHttpCachingInterceptorService } from './ng-http-caching-interceptor.service';
5
- import * as i0 from "@angular/core";
6
- export class NgHttpCachingModule {
7
- static forRoot(ngHttpCachingConfig) {
8
- return {
9
- ngModule: NgHttpCachingModule,
10
- providers: [
11
- {
12
- provide: NG_HTTP_CACHING_CONFIG,
13
- useValue: ngHttpCachingConfig,
14
- },
15
- ],
16
- };
17
- }
18
- }
19
- NgHttpCachingModule.ɵfac = function NgHttpCachingModule_Factory(t) { return new (t || NgHttpCachingModule)(); };
20
- NgHttpCachingModule.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: NgHttpCachingModule });
21
- NgHttpCachingModule.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ providers: [
22
- NgHttpCachingService,
23
- {
24
- provide: HTTP_INTERCEPTORS,
25
- useClass: NgHttpCachingInterceptorService,
26
- multi: true,
27
- },
28
- ], imports: [[]] });
29
- (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NgHttpCachingModule, [{
30
- type: NgModule,
31
- args: [{
32
- declarations: [],
33
- imports: [],
34
- providers: [
35
- NgHttpCachingService,
36
- {
37
- provide: HTTP_INTERCEPTORS,
38
- useClass: NgHttpCachingInterceptorService,
39
- multi: true,
40
- },
41
- ],
42
- exports: [],
43
- }]
44
- }], null, null); })();
45
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctaHR0cC1jYWNoaW5nLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWh0dHAtY2FjaGluZy9zcmMvbGliL25nLWh0dHAtY2FjaGluZy5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBdUIsTUFBTSxlQUFlLENBQUM7QUFDOUQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDekQsT0FBTyxFQUNMLHNCQUFzQixFQUV0QixvQkFBb0IsR0FDckIsTUFBTSwyQkFBMkIsQ0FBQztBQUNuQyxPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQzs7QUFleEYsTUFBTSxPQUFPLG1CQUFtQjtJQUM5QixNQUFNLENBQUMsT0FBTyxDQUNaLG1CQUF5QztRQUV6QyxPQUFPO1lBQ0wsUUFBUSxFQUFFLG1CQUFtQjtZQUM3QixTQUFTLEVBQUU7Z0JBQ1Q7b0JBQ0UsT0FBTyxFQUFFLHNCQUFzQjtvQkFDL0IsUUFBUSxFQUFFLG1CQUFtQjtpQkFDOUI7YUFDRjtTQUNGLENBQUM7SUFDSixDQUFDOztzRkFiVSxtQkFBbUI7cUVBQW5CLG1CQUFtQjswRUFWbkI7UUFDVCxvQkFBb0I7UUFDcEI7WUFDRSxPQUFPLEVBQUUsaUJBQWlCO1lBQzFCLFFBQVEsRUFBRSwrQkFBK0I7WUFDekMsS0FBSyxFQUFFLElBQUk7U0FDWjtLQUNGLFlBUlEsRUFBRTt1RkFXQSxtQkFBbUI7Y0FiL0IsUUFBUTtlQUFDO2dCQUNSLFlBQVksRUFBRSxFQUFFO2dCQUNoQixPQUFPLEVBQUUsRUFBRTtnQkFDWCxTQUFTLEVBQUU7b0JBQ1Qsb0JBQW9CO29CQUNwQjt3QkFDRSxPQUFPLEVBQUUsaUJBQWlCO3dCQUMxQixRQUFRLEVBQUUsK0JBQStCO3dCQUN6QyxLQUFLLEVBQUUsSUFBSTtxQkFDWjtpQkFDRjtnQkFDRCxPQUFPLEVBQUUsRUFBRTthQUNaIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdNb2R1bGUsIE1vZHVsZVdpdGhQcm92aWRlcnMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgSFRUUF9JTlRFUkNFUFRPUlMgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7XHJcbiAgTkdfSFRUUF9DQUNISU5HX0NPTkZJRyxcclxuICBOZ0h0dHBDYWNoaW5nQ29uZmlnLFxyXG4gIE5nSHR0cENhY2hpbmdTZXJ2aWNlLFxyXG59IGZyb20gJy4vbmctaHR0cC1jYWNoaW5nLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBOZ0h0dHBDYWNoaW5nSW50ZXJjZXB0b3JTZXJ2aWNlIH0gZnJvbSAnLi9uZy1odHRwLWNhY2hpbmctaW50ZXJjZXB0b3Iuc2VydmljZSc7XHJcblxyXG5ATmdNb2R1bGUoe1xyXG4gIGRlY2xhcmF0aW9uczogW10sXHJcbiAgaW1wb3J0czogW10sXHJcbiAgcHJvdmlkZXJzOiBbXHJcbiAgICBOZ0h0dHBDYWNoaW5nU2VydmljZSxcclxuICAgIHtcclxuICAgICAgcHJvdmlkZTogSFRUUF9JTlRFUkNFUFRPUlMsXHJcbiAgICAgIHVzZUNsYXNzOiBOZ0h0dHBDYWNoaW5nSW50ZXJjZXB0b3JTZXJ2aWNlLFxyXG4gICAgICBtdWx0aTogdHJ1ZSxcclxuICAgIH0sXHJcbiAgXSxcclxuICBleHBvcnRzOiBbXSxcclxufSlcclxuZXhwb3J0IGNsYXNzIE5nSHR0cENhY2hpbmdNb2R1bGUge1xyXG4gIHN0YXRpYyBmb3JSb290KFxyXG4gICAgbmdIdHRwQ2FjaGluZ0NvbmZpZz86IE5nSHR0cENhY2hpbmdDb25maWdcclxuICApOiBNb2R1bGVXaXRoUHJvdmlkZXJzPE5nSHR0cENhY2hpbmdNb2R1bGU+IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIG5nTW9kdWxlOiBOZ0h0dHBDYWNoaW5nTW9kdWxlLFxyXG4gICAgICBwcm92aWRlcnM6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBwcm92aWRlOiBOR19IVFRQX0NBQ0hJTkdfQ09ORklHLFxyXG4gICAgICAgICAgdXNlVmFsdWU6IG5nSHR0cENhY2hpbmdDb25maWcsXHJcbiAgICAgICAgfSxcclxuICAgICAgXSxcclxuICAgIH07XHJcbiAgfVxyXG59XHJcbiJdfQ==
@@ -1,260 +0,0 @@
1
- import { Injectable, InjectionToken, Inject, Optional } from '@angular/core';
2
- import { NgHttpCachingMemoryStorage } from './storage/ng-http-caching-memory-storage';
3
- import * as i0 from "@angular/core";
4
- export const NG_HTTP_CACHING_CONFIG = new InjectionToken('ng-http-caching.config');
5
- export var NgHttpCachingStrategy;
6
- (function (NgHttpCachingStrategy) {
7
- NgHttpCachingStrategy["ALLOW_ALL"] = "ALLOW_ALL";
8
- NgHttpCachingStrategy["DISALLOW_ALL"] = "DISALLOW_ALL";
9
- })(NgHttpCachingStrategy || (NgHttpCachingStrategy = {}));
10
- export var NgHttpCachingHeaders;
11
- (function (NgHttpCachingHeaders) {
12
- NgHttpCachingHeaders["ALLOW_CACHE"] = "X-NG-HTTP-CACHING-ALLOW-CACHE";
13
- NgHttpCachingHeaders["DISALLOW_CACHE"] = "X-NG-HTTP-CACHING-DISALLOW-CACHE";
14
- NgHttpCachingHeaders["LIFETIME"] = "X-NG-HTTP-CACHING-LIFETIME";
15
- NgHttpCachingHeaders["TAG"] = "X-NG-HTTP-CACHING-TAG";
16
- })(NgHttpCachingHeaders || (NgHttpCachingHeaders = {}));
17
- export class NgHttpCachingConfig {
18
- }
19
- export const NgHttpCachingConfigDefault = {
20
- store: new NgHttpCachingMemoryStorage(),
21
- lifetime: 60 * 60 * 100,
22
- allowedMethod: ['GET'],
23
- cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,
24
- };
25
- export class NgHttpCachingService {
26
- constructor(config) {
27
- this.queue = new Map();
28
- if (config) {
29
- this.config = Object.assign(Object.assign({}, NgHttpCachingConfigDefault), config);
30
- }
31
- else {
32
- this.config = NgHttpCachingConfigDefault;
33
- }
34
- }
35
- /**
36
- * Return the config
37
- */
38
- getConfig() {
39
- return this.config;
40
- }
41
- /**
42
- * Return the queue map
43
- */
44
- getQueue() {
45
- return this.queue;
46
- }
47
- /**
48
- * Return the cache store
49
- */
50
- getStore() {
51
- return this.config.store;
52
- }
53
- /**
54
- * Return response from cache
55
- */
56
- getFromCache(req) {
57
- const key = this.getKey(req);
58
- const cached = this.config.store.get(key);
59
- if (!cached) {
60
- return undefined;
61
- }
62
- if (this.isExpired(cached)) {
63
- this.clearCacheByKey(key);
64
- return undefined;
65
- }
66
- return cached.response;
67
- }
68
- /**
69
- * Add response to cache
70
- */
71
- addToCache(req, res) {
72
- const key = this.getKey(req);
73
- const entry = {
74
- url: req.urlWithParams,
75
- response: res,
76
- request: req,
77
- addedTime: Date.now(),
78
- };
79
- if (this.isValid(entry)) {
80
- this.config.store.set(key, entry);
81
- return true;
82
- }
83
- return false;
84
- }
85
- /**
86
- * Delete response from cache
87
- */
88
- deleteFromCache(req) {
89
- const key = this.getKey(req);
90
- return this.clearCacheByKey(key);
91
- }
92
- /**
93
- * Clear the cache
94
- */
95
- clearCache() {
96
- this.config.store.clear();
97
- }
98
- /**
99
- * Clear the cache by key
100
- */
101
- clearCacheByKey(key) {
102
- return this.config.store.delete(key);
103
- }
104
- /**
105
- * Clear the cache by regex
106
- */
107
- clearCacheByRegex(regex) {
108
- this.config.store.forEach((entry, key) => {
109
- if (regex.test(key)) {
110
- this.clearCacheByKey(key);
111
- }
112
- });
113
- }
114
- /**
115
- * Clear the cache by TAG
116
- */
117
- clearCacheByTag(tag) {
118
- this.config.store.forEach((entry, key) => {
119
- const tagHeader = entry.request.headers.get(NgHttpCachingHeaders.TAG);
120
- if (tagHeader && tagHeader.split(',').includes(tag)) {
121
- this.clearCacheByKey(key);
122
- }
123
- });
124
- }
125
- /**
126
- * Run garbage collector (delete expired cache entry)
127
- */
128
- runGc() {
129
- this.config.store.forEach((entry, key) => {
130
- if (this.isExpired(entry)) {
131
- this.clearCacheByKey(key);
132
- }
133
- });
134
- }
135
- /**
136
- * Return true if cache entry is expired
137
- */
138
- isExpired(entry) {
139
- // if user provide custom method, use it
140
- if (typeof this.config.isExpired === 'function') {
141
- const result = this.config.isExpired(entry);
142
- // if result is undefined, normal behaviour is provided
143
- if (typeof result !== 'undefined') {
144
- return result;
145
- }
146
- }
147
- // config/default lifetime
148
- let lifetime = this.config.lifetime;
149
- // request has own lifetime
150
- if (entry.request.headers.has(NgHttpCachingHeaders.LIFETIME)) {
151
- lifetime = +entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);
152
- }
153
- // never expire if 0
154
- if (lifetime === 0) {
155
- return false;
156
- }
157
- // wrong lifetime
158
- if (lifetime < 0) {
159
- throw new Error('lifetime must be greater than or equal 0');
160
- }
161
- return entry.addedTime + lifetime < Date.now();
162
- }
163
- /**
164
- * Return true if cache entry is valid for store in the cache
165
- */
166
- isValid(entry) {
167
- // if user provide custom method, use it
168
- if (typeof this.config.isValid === 'function') {
169
- const result = this.config.isValid(entry);
170
- // if result is undefined, normal behaviour is provided
171
- if (typeof result !== 'undefined') {
172
- return result;
173
- }
174
- }
175
- return true;
176
- }
177
- /**
178
- * Return true if the request is cacheable
179
- */
180
- isCacheable(req) {
181
- // if user provide custom method, use it
182
- if (typeof this.config.isCacheable === 'function') {
183
- const result = this.config.isCacheable(req);
184
- // if result is undefined, normal behaviour is provided
185
- if (typeof result !== 'undefined') {
186
- return result;
187
- }
188
- }
189
- // request has disallow cache header
190
- if (req.headers.has(NgHttpCachingHeaders.DISALLOW_CACHE)) {
191
- return false;
192
- }
193
- // strategy is disallow all...
194
- if (this.config.cacheStrategy === NgHttpCachingStrategy.DISALLOW_ALL) {
195
- // request isn't allowed if come without allow header
196
- if (!req.headers.has(NgHttpCachingHeaders.ALLOW_CACHE)) {
197
- return false;
198
- }
199
- }
200
- // if allowed method is only ALL, allow all http methos
201
- if (this.config.allowedMethod.length === 1) {
202
- if (this.config.allowedMethod[0] === 'ALL') {
203
- return true;
204
- }
205
- }
206
- // request is allowed if method is in allowedMethod
207
- return this.config.allowedMethod.indexOf(req.method) !== -1;
208
- }
209
- /**
210
- * Return the cache key
211
- */
212
- getKey(req) {
213
- // if user provide custom method, use it
214
- if (typeof this.config.getKey === 'function') {
215
- const result = this.config.getKey(req);
216
- // if result is undefined, normal behaviour is provided
217
- if (typeof result !== 'undefined') {
218
- return result;
219
- }
220
- }
221
- // default key id is url with query parameters
222
- return req.urlWithParams;
223
- }
224
- /**
225
- * Return observable from cache
226
- */
227
- getFromQueue(req) {
228
- const key = this.getKey(req);
229
- const cached = this.queue.get(key);
230
- if (!cached) {
231
- return undefined;
232
- }
233
- return cached;
234
- }
235
- /**
236
- * Add observable to cache
237
- */
238
- addToQueue(req, obs) {
239
- const key = this.getKey(req);
240
- this.queue.set(key, obs);
241
- }
242
- /**
243
- * Delete observable from cache
244
- */
245
- deleteFromQueue(req) {
246
- const key = this.getKey(req);
247
- return this.queue.delete(key);
248
- }
249
- }
250
- NgHttpCachingService.ɵfac = function NgHttpCachingService_Factory(t) { return new (t || NgHttpCachingService)(i0.ɵɵinject(NG_HTTP_CACHING_CONFIG, 8)); };
251
- NgHttpCachingService.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: NgHttpCachingService, factory: NgHttpCachingService.ɵfac });
252
- (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NgHttpCachingService, [{
253
- type: Injectable
254
- }], function () { return [{ type: NgHttpCachingConfig, decorators: [{
255
- type: Inject,
256
- args: [NG_HTTP_CACHING_CONFIG]
257
- }, {
258
- type: Optional
259
- }] }]; }, null); })();
260
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctaHR0cC1jYWNoaW5nLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1odHRwLWNhY2hpbmcvc3JjL2xpYi9uZy1odHRwLWNhY2hpbmcuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBSTdFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDBDQUEwQyxDQUFDOztBQVN0RixNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLGNBQWMsQ0FDdEQsd0JBQXdCLENBQ3pCLENBQUM7QUFFRixNQUFNLENBQU4sSUFBWSxxQkFHWDtBQUhELFdBQVkscUJBQXFCO0lBQy9CLGdEQUF1QixDQUFBO0lBQ3ZCLHNEQUE2QixDQUFBO0FBQy9CLENBQUMsRUFIVyxxQkFBcUIsS0FBckIscUJBQXFCLFFBR2hDO0FBRUQsTUFBTSxDQUFOLElBQVksb0JBS1g7QUFMRCxXQUFZLG9CQUFvQjtJQUM5QixxRUFBNkMsQ0FBQTtJQUM3QywyRUFBbUQsQ0FBQTtJQUNuRCwrREFBdUMsQ0FBQTtJQUN2QyxxREFBNkIsQ0FBQTtBQUMvQixDQUFDLEVBTFcsb0JBQW9CLEtBQXBCLG9CQUFvQixRQUsvQjtBQUNELE1BQU0sT0FBTyxtQkFBbUI7Q0FTL0I7QUFFRCxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBd0I7SUFDN0QsS0FBSyxFQUFFLElBQUksMEJBQTBCLEVBQUU7SUFDdkMsUUFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsR0FBRztJQUN2QixhQUFhLEVBQUUsQ0FBQyxLQUFLLENBQUM7SUFDdEIsYUFBYSxFQUFFLHFCQUFxQixDQUFDLFNBQVM7Q0FDL0MsQ0FBQztBQUdGLE1BQU0sT0FBTyxvQkFBb0I7SUFNL0IsWUFDOEMsTUFBMkI7UUFMakUsVUFBSyxHQUFH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LEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sTUFBTSxHQUErQixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUUvRCxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ1gsT0FBTyxTQUFTLENBQUM7U0FDbEI7UUFFRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxVQUFVLENBQUMsR0FBcUIsRUFBRSxHQUErQjtRQUMvRCxNQUFNLEdBQUcsR0FBVyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxlQUFlLENBQUMsR0FBcUI7UUFDbkMsTUFBTSxHQUFHLEdBQVcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNyQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7O3dGQTNQVSxvQkFBb0IsY0FPckIsc0JBQXNCOzBFQVByQixvQkFBb0IsV0FBcEIsb0JBQW9CO3VGQUFwQixvQkFBb0I7Y0FEaEMsVUFBVTtzQ0FRNkMsbUJBQW1CO3NCQUF0RSxNQUFNO3VCQUFDLHNCQUFzQjs7c0JBQUcsUUFBUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdGlvblRva2VuLCBJbmplY3QsIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2UsIEh0dHBFdmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMvaW50ZXJuYWwvT2JzZXJ2YWJsZSc7XHJcbmltcG9ydCB7IE5nSHR0cENhY2hpbmdTdG9yYWdlSW50ZXJmYWNlIH0gZnJvbSAnLi9zdG9yYWdlL25nLWh0dHAtY2FjaGluZy1zdG9yYWdlLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IE5nSHR0cENhY2hpbmdNZW1vcnlTdG9yYWdlIH0gZnJvbSAnLi9zdG9yYWdlL25nLWh0dHAtY2FjaGluZy1tZW1vcnktc3RvcmFnZSc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIE5nSHR0cENhY2hpbmdFbnRyeSB7XHJcbiAgdXJsOiBzdHJpbmc7XHJcbiAgcmVzcG9uc2U6IEh0dHBSZXNwb25zZTxhbnk+O1xyXG4gIHJlcXVlc3Q6IEh0dHBSZXF1ZXN0PGFueT47XHJcbiAgYWRkZWRUaW1lOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBOR19IVFRQX0NBQ0hJTkdfQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPE5nSHR0cENhY2hpbmdDb25maWc+KFxyXG4gICduZy1odHRwLWNhY2hpbmcuY29uZmlnJ1xyXG4pO1xyXG5cclxuZXhwb3J0IGVudW0gTmdIdHRwQ2FjaGluZ1N0cmF0ZWd5IHtcclxuICBBTExPV19BTEwgPSAnQUxMT1dfQUxMJyxcclxuICBESVNBTExPV19BTEwgPSAnRElTQUxMT1dfQUxMJyxcclxufVxyXG5cclxuZXhwb3J0IGVudW0gTmdIdHRwQ2FjaGluZ0hlYWRlcnMge1xyXG4gIEFMTE9XX0NBQ0hFID0gJ1gtTkctSFRUUC1DQUNISU5HLUFMTE9XLUNBQ0hFJyxcclxuICBESVNBTExPV19DQUNIRSA9ICdYLU5HLUhUVFAtQ0FDSElORy1ESVNBTExPVy1DQUNIRScsXHJcbiAgTElGRVRJTUUgPSAnWC1ORy1IVFRQLUNBQ0hJTkctTElGRVRJTUUnLFxyXG4gIFRBRyA9ICdYLU5HLUhUVFAtQ0FDSElORy1UQUcnLFxyXG59XHJcbmV4cG9ydCBjbGFzcyBOZ0h0dHBDYWNoaW5nQ29uZmlnIHtcclxuICBzdG9yZT86IE5nSHR0cENhY2hpbmdTdG9yYWdlSW50ZXJmYWNlO1xyXG4gIGxpZmV0aW1lPzogbnVtYmVyO1xyXG4gIGFsbG93ZWRNZXRob2Q/OiBzdHJpbmdbXTtcclxuICBjYWNoZVN0cmF0ZWd5PzogTmdIdHRwQ2FjaGluZ1N0cmF0ZWd5O1xyXG4gIGlzRXhwaXJlZD86IChlbnRyeTogTmdIdHRwQ2FjaGluZ0VudHJ5KSA9PiBib29sZWFuIHwgdW5kZWZpbmVkO1xyXG4gIGlzQ2FjaGVhYmxlPzogKHJlcTogSHR0cFJlcXVlc3Q8YW55PikgPT4gYm9vbGVhbiB8IHVuZGVmaW5lZDtcclxuICBnZXRLZXk/OiAocmVxOiBIdHRwUmVxdWVzdDxhbnk+KSA9PiBzdHJpbmcgfCB1bmRlZmluZWQ7XHJcbiAgaXNWYWxpZD86IChlbnRyeTogTmdIdHRwQ2FjaGluZ0VudHJ5KSA9PiBib29sZWFuIHwgdW5kZWZpbmVkO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgTmdIdHRwQ2FjaGluZ0NvbmZpZ0RlZmF1bHQ6IE5nSHR0cENhY2hpbmdDb25maWcgPSB7XHJcbiAgc3RvcmU6IG5ldyBOZ0h0dHBDYWNoaW5nTWVtb3J5U3RvcmFnZSgpLFxyXG4gIGxpZmV0aW1lOiA2MCAqIDYwICogMTAwLFxyXG4gIGFsbG93ZWRNZXRob2Q6IFsnR0VUJ10sXHJcbiAgY2FjaGVTdHJhdGVneTogTmdIdHRwQ2FjaGluZ1N0cmF0ZWd5LkFMTE9XX0FMTCxcclxufTtcclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIE5nSHR0cENhY2hpbmdTZXJ2aWNlIHtcclxuXHJcbiAgcHJpdmF0ZSBxdWV1ZSA9IG5ldyBNYXA8c3RyaW5nLCBPYnNlcnZhYmxlPEh0dHBFdmVudDxhbnk+Pj4oKTtcclxuXHJcbiAgcHJpdmF0ZSBjb25maWc6IE5nSHR0cENhY2hpbmdDb25maWc7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgQEluamVjdChOR19IVFRQX0NBQ0hJTkdfQ09ORklHKSBAT3B0aW9uYWwoKSBjb25maWc6IE5nSHR0cENhY2hpbmdDb25maWdcclxuICApIHtcclxuICAgIGlmIChjb25maWcpIHtcclxuICAgICAgdGhpcy5jb25maWcgPSB7IC4uLk5nSHR0cENhY2hpbmdDb25maWdEZWZhdWx0LCAuLi5jb25maWcgfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuY29uZmlnID0gTmdIdHRwQ2FjaGluZ0NvbmZpZ0RlZmF1bHQ7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gdGhlIGNvbmZpZ1xyXG4gICAqL1xyXG4gIGdldENvbmZpZygpOiBOZ0h0dHBDYWNoaW5nQ29uZmlnIHtcclxuICAgIHJldHVybiB0aGlzLmNvbmZpZztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybiB0aGUgcXVldWUgbWFwXHJcbiAgICovXHJcbiAgZ2V0UXVldWUoKTogTWFwPHN0cmluZywgT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4+IHtcclxuICAgIHJldHVybiB0aGlzLnF1ZXVlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJuIHRoZSBjYWNoZSBzdG9yZVxyXG4gICAqL1xyXG4gIGdldFN0b3JlKCk6IE5nSHR0cENhY2hpbmdTdG9yYWdlSW50ZXJmYWNlIHtcclxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5zdG9yZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybiByZXNwb25zZSBmcm9tIGNhY2hlXHJcbiAgICovXHJcbiAgZ2V0RnJvbUNhY2hlKHJlcTogSHR0cFJlcXVlc3Q8YW55Pik6IEh0dHBSZXNwb25zZTxhbnk+IHwgdW5kZWZpbmVkIHtcclxuICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgIGNvbnN0IGNhY2hlZDogTmdIdHRwQ2FjaGluZ0VudHJ5ID0gdGhpcy5jb25maWcuc3RvcmUuZ2V0KGtleSk7XHJcblxyXG4gICAgaWYgKCFjYWNoZWQpIHtcclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5pc0V4cGlyZWQoY2FjaGVkKSkge1xyXG4gICAgICB0aGlzLmNsZWFyQ2FjaGVCeUtleShrZXkpO1xyXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjYWNoZWQucmVzcG9uc2U7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBZGQgcmVzcG9uc2UgdG8gY2FjaGVcclxuICAgKi9cclxuICBhZGRUb0NhY2hlKHJlcTogSHR0cFJlcXVlc3Q8YW55PiwgcmVzOiBIdHRwUmVzcG9uc2U8YW55Pik6IGJvb2xlYW4ge1xyXG4gICAgY29uc3Qga2V5OiBzdHJpbmcgPSB0aGlzLmdldEtleShyZXEpO1xyXG4gICAgY29uc3QgZW50cnk6IE5nSHR0cENhY2hpbmdFbnRyeSA9IHtcclxuICAgICAgdXJsOiByZXEudXJsV2l0aFBhcmFtcyxcclxuICAgICAgcmVzcG9uc2U6IHJlcyxcclxuICAgICAgcmVxdWVzdDogcmVxLFxyXG4gICAgICBhZGRlZFRpbWU6IERhdGUubm93KCksXHJcbiAgICB9O1xyXG4gICAgaWYgKCB0aGlzLmlzVmFsaWQoZW50cnkpICkge1xyXG4gICAgICB0aGlzLmNvbmZpZy5zdG9yZS5zZXQoa2V5LCBlbnRyeSk7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVsZXRlIHJlc3BvbnNlIGZyb20gY2FjaGVcclxuICAgKi9cclxuICBkZWxldGVGcm9tQ2FjaGUocmVxOiBIdHRwUmVxdWVzdDxhbnk+KTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBrZXk6IHN0cmluZyA9IHRoaXMuZ2V0S2V5KHJlcSk7XHJcbiAgICByZXR1cm4gdGhpcy5jbGVhckNhY2hlQnlLZXkoa2V5KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENsZWFyIHRoZSBjYWNoZVxyXG4gICAqL1xyXG4gIGNsZWFyQ2FjaGUoKTogdm9pZCB7XHJcbiAgICB0aGlzLmNvbmZpZy5zdG9yZS5jbGVhcigpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xlYXIgdGhlIGNhY2hlIGJ5IGtleVxyXG4gICAqL1xyXG4gIGNsZWFyQ2FjaGVCeUtleShrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnN0b3JlLmRlbGV0ZShrZXkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xlYXIgdGhlIGNhY2hlIGJ5IHJlZ2V4XHJcbiAgICovXHJcbiAgY2xlYXJDYWNoZUJ5UmVnZXgocmVnZXg6IFJlZ0V4cCk6IHZvaWQge1xyXG4gICAgdGhpcy5jb25maWcuc3RvcmUuZm9yRWFjaCgoZW50cnk6IE5nSHR0cENhY2hpbmdFbnRyeSwga2V5OiBzdHJpbmcpID0+IHtcclxuICAgICAgaWYgKCByZWdleC50ZXN0KGtleSkgKXtcclxuICAgICAgICB0aGlzLmNsZWFyQ2FjaGVCeUtleShrZXkpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENsZWFyIHRoZSBjYWNoZSBieSBUQUdcclxuICAgKi9cclxuICBjbGVhckNhY2hlQnlUYWcodGFnOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRoaXMuY29uZmlnLnN0b3JlLmZvckVhY2goKGVudHJ5OiBOZ0h0dHBDYWNoaW5nRW50cnksIGtleTogc3RyaW5nKSA9PiB7XHJcbiAgICAgIGNvbnN0IHRhZ0hlYWRlciA9IGVudHJ5LnJlcXVlc3QuaGVhZGVycy5nZXQoTmdIdHRwQ2FjaGluZ0hlYWRlcnMuVEFHKTtcclxuICAgICAgaWYgKCB0YWdIZWFkZXIgJiYgdGFnSGVhZGVyLnNwbGl0KCcsJykuaW5jbHVkZXModGFnKSApe1xyXG4gICAgICAgIHRoaXMuY2xlYXJDYWNoZUJ5S2V5KGtleSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUnVuIGdhcmJhZ2UgY29sbGVjdG9yIChkZWxldGUgZXhwaXJlZCBjYWNoZSBlbnRyeSlcclxuICAgKi9cclxuICBydW5HYygpOiB2b2lkIHtcclxuICAgIHRoaXMuY29uZmlnLnN0b3JlLmZvckVhY2goKGVudHJ5OiBOZ0h0dHBDYWNoaW5nRW50cnksIGtleTogc3RyaW5nKSA9PiB7XHJcbiAgICAgIGlmICggdGhpcy5pc0V4cGlyZWQoZW50cnkpICl7XHJcbiAgICAgICAgdGhpcy5jbGVhckNhY2hlQnlLZXkoa2V5KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gdHJ1ZSBpZiBjYWNoZSBlbnRyeSBpcyBleHBpcmVkXHJcbiAgICovXHJcbiAgaXNFeHBpcmVkKGVudHJ5OiBOZ0h0dHBDYWNoaW5nRW50cnkpOiBib29sZWFuIHtcclxuICAgIC8vIGlmIHVzZXIgcHJvdmlkZSBjdXN0b20gbWV0aG9kLCB1c2UgaXRcclxuICAgIGlmICh0eXBlb2YgdGhpcy5jb25maWcuaXNFeHBpcmVkID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuY29uZmlnLmlzRXhwaXJlZChlbnRyeSk7XHJcbiAgICAgIC8vIGlmIHJlc3VsdCBpcyB1bmRlZmluZWQsIG5vcm1hbCBiZWhhdmlvdXIgaXMgcHJvdmlkZWRcclxuICAgICAgaWYgKHR5cGVvZiByZXN1bHQgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gY29uZmlnL2RlZmF1bHQgbGlmZXRpbWVcclxuICAgIGxldCBsaWZldGltZSA9IHRoaXMuY29uZmlnLmxpZmV0aW1lO1xyXG4gICAgLy8gcmVxdWVzdCBoYXMgb3duIGxpZmV0aW1lXHJcbiAgICBpZiAoZW50cnkucmVxdWVzdC5oZWFkZXJzLmhhcyhOZ0h0dHBDYWNoaW5nSGVhZGVycy5MSUZFVElNRSkpIHtcclxuICAgICAgbGlmZXRpbWUgPSArZW50cnkucmVxdWVzdC5oZWFkZXJzLmdldChOZ0h0dHBDYWNoaW5nSGVhZGVycy5MSUZFVElNRSk7XHJcbiAgICB9XHJcbiAgICAvLyBuZXZlciBleHBpcmUgaWYgMFxyXG4gICAgaWYgKGxpZmV0aW1lID09PSAwKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIC8vIHdyb25nIGxpZmV0aW1lXHJcbiAgICBpZiAobGlmZXRpbWUgPCAwKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGlmZXRpbWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgMCcpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGVudHJ5LmFkZGVkVGltZSArIGxpZmV0aW1lIDwgRGF0ZS5ub3coKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybiB0cnVlIGlmIGNhY2hlIGVudHJ5IGlzIHZhbGlkIGZvciBzdG9yZSBpbiB0aGUgY2FjaGVcclxuICAgKi9cclxuICBpc1ZhbGlkKGVudHJ5OiBOZ0h0dHBDYWNoaW5nRW50cnkpOiBib29sZWFuIHtcclxuICAgIC8vIGlmIHVzZXIgcHJvdmlkZSBjdXN0b20gbWV0aG9kLCB1c2UgaXRcclxuICAgIGlmICh0eXBlb2YgdGhpcy5jb25maWcuaXNWYWxpZCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmNvbmZpZy5pc1ZhbGlkKGVudHJ5KTtcclxuICAgICAgLy8gaWYgcmVzdWx0IGlzIHVuZGVmaW5lZCwgbm9ybWFsIGJlaGF2aW91ciBpcyBwcm92aWRlZFxyXG4gICAgICBpZiAodHlwZW9mIHJlc3VsdCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybiB0cnVlIGlmIHRoZSByZXF1ZXN0IGlzIGNhY2hlYWJsZVxyXG4gICAqL1xyXG4gIGlzQ2FjaGVhYmxlKHJlcTogSHR0cFJlcXVlc3Q8YW55Pik6IGJvb2xlYW4ge1xyXG4gICAgLy8gaWYgdXNlciBwcm92aWRlIGN1c3RvbSBtZXRob2QsIHVzZSBpdFxyXG4gICAgaWYgKHR5cGVvZiB0aGlzLmNvbmZpZy5pc0NhY2hlYWJsZSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmNvbmZpZy5pc0NhY2hlYWJsZShyZXEpO1xyXG4gICAgICAvLyBpZiByZXN1bHQgaXMgdW5kZWZpbmVkLCBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkXHJcbiAgICAgIGlmICh0eXBlb2YgcmVzdWx0ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIHJlcXVlc3QgaGFzIGRpc2FsbG93IGNhY2hlIGhlYWRlclxyXG4gICAgaWYgKHJlcS5oZWFkZXJzLmhhcyhOZ0h0dHBDYWNoaW5nSGVhZGVycy5ESVNBTExPV19DQUNIRSkpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgLy8gc3RyYXRlZ3kgaXMgZGlzYWxsb3cgYWxsLi4uXHJcbiAgICBpZiAodGhpcy5jb25maWcuY2FjaGVTdHJhdGVneSA9PT0gTmdIdHRwQ2FjaGluZ1N0cmF0ZWd5LkRJU0FMTE9XX0FMTCkge1xyXG4gICAgICAvLyByZXF1ZXN0IGlzbid0IGFsbG93ZWQgaWYgY29tZSB3aXRob3V0IGFsbG93IGhlYWRlclxyXG4gICAgICBpZiAoIXJlcS5oZWFkZXJzLmhhcyhOZ0h0dHBDYWNoaW5nSGVhZGVycy5BTExPV19DQUNIRSkpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIGlmIGFsbG93ZWQgbWV0aG9kIGlzIG9ubHkgQUxMLCBhbGxvdyBhbGwgaHR0cCBtZXRob3NcclxuICAgIGlmICggdGhpcy5jb25maWcuYWxsb3dlZE1ldGhvZC5sZW5ndGggPT09IDEpIHtcclxuICAgICAgaWYgKHRoaXMuY29uZmlnLmFsbG93ZWRNZXRob2RbMF0gPT09ICdBTEwnKXtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gcmVxdWVzdCBpcyBhbGxvd2VkIGlmIG1ldGhvZCBpcyBpbiBhbGxvd2VkTWV0aG9kXHJcbiAgICByZXR1cm4gdGhpcy5jb25maWcuYWxsb3dlZE1ldGhvZC5pbmRleE9mKHJlcS5tZXRob2QpICE9PSAtMTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybiB0aGUgY2FjaGUga2V5XHJcbiAgICovXHJcbiAgZ2V0S2V5KHJlcTogSHR0cFJlcXVlc3Q8YW55Pik6IHN0cmluZyB7XHJcbiAgICAvLyBpZiB1c2VyIHByb3ZpZGUgY3VzdG9tIG1ldGhvZCwgdXNlIGl0XHJcbiAgICBpZiAodHlwZW9mIHRoaXMuY29uZmlnLmdldEtleSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmNvbmZpZy5nZXRLZXkocmVxKTtcclxuICAgICAgLy8gaWYgcmVzdWx0IGlzIHVuZGVmaW5lZCwgbm9ybWFsIGJlaGF2aW91ciBpcyBwcm92aWRlZFxyXG4gICAgICBpZiAodHlwZW9mIHJlc3VsdCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBkZWZhdWx0IGtleSBpZCBpcyB1cmwgd2l0aCBxdWVyeSBwYXJhbWV0ZXJzXHJcbiAgICByZXR1cm4gcmVxLnVybFdpdGhQYXJhbXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gb2JzZXJ2YWJsZSBmcm9tIGNhY2hlXHJcbiAgICovXHJcbiAgZ2V0RnJvbVF1ZXVlKHJlcTogSHR0cFJlcXVlc3Q8YW55Pik6IE9ic2VydmFibGU8SHR0cEV2ZW50PGFueT4+IHwgdW5kZWZpbmVkIHtcclxuICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgIGNvbnN0IGNhY2hlZDogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4gPSB0aGlzLnF1ZXVlLmdldChrZXkpO1xyXG5cclxuICAgIGlmICghY2FjaGVkKSB7XHJcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGNhY2hlZDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZCBvYnNlcnZhYmxlIHRvIGNhY2hlXHJcbiAgICovXHJcbiAgYWRkVG9RdWV1ZShyZXE6IEh0dHBSZXF1ZXN0PGFueT4sIG9iczogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4pOiB2b2lkIHtcclxuICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgIHRoaXMucXVldWUuc2V0KGtleSwgb2JzKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlbGV0ZSBvYnNlcnZhYmxlIGZyb20gY2FjaGVcclxuICAgKi9cclxuICBkZWxldGVGcm9tUXVldWUocmVxOiBIdHRwUmVxdWVzdDxhbnk+KTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBrZXk6IHN0cmluZyA9IHRoaXMuZ2V0S2V5KHJlcSk7XHJcbiAgICByZXR1cm4gdGhpcy5xdWV1ZS5kZWxldGUoa2V5KTtcclxuICB9XHJcbn1cclxuIl19
@@ -1,27 +0,0 @@
1
- export class NgHttpCachingMemoryStorage {
2
- constructor() {
3
- this.store = new Map();
4
- }
5
- get size() {
6
- return this.store.size;
7
- }
8
- clear() {
9
- this.store.clear();
10
- }
11
- delete(key) {
12
- return this.store.delete(key);
13
- }
14
- forEach(callbackfn) {
15
- return this.store.forEach(callbackfn);
16
- }
17
- get(key) {
18
- return this.store.get(key);
19
- }
20
- has(key) {
21
- return this.store.has(key);
22
- }
23
- set(key, value) {
24
- this.store.set(key, value);
25
- }
26
- }
27
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctaHR0cC1jYWNoaW5nLW1lbW9yeS1zdG9yYWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctaHR0cC1jYWNoaW5nL3NyYy9saWIvc3RvcmFnZS9uZy1odHRwLWNhY2hpbmctbWVtb3J5LXN0b3JhZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsTUFBTSxPQUFPLDBCQUEwQjtJQUF2QztRQU1ZLFVBQUssR0FBRyxJQUFJLEdBQUcsRUFBOEIsQ0FBQztJQXlCMUQsQ0FBQztJQTdCRyxJQUFJLElBQUk7UUFDSixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO0lBQzNCLENBQUM7SUFJRCxLQUFLO1FBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQsTUFBTSxDQUFDLEdBQVc7UUFDZCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRCxPQUFPLENBQUMsVUFBNEQ7UUFDaEUsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsR0FBRyxDQUFDLEdBQVc7UUFDWCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQy9CLENBQUM7SUFFRCxHQUFHLENBQUMsR0FBVztRQUNYLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVELEdBQUcsQ0FBQyxHQUFXLEVBQUUsS0FBeUI7UUFDdEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQy9CLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nSHR0cENhY2hpbmdTdG9yYWdlSW50ZXJmYWNlIH0gZnJvbSAnLi9uZy1odHRwLWNhY2hpbmctc3RvcmFnZS5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBOZ0h0dHBDYWNoaW5nRW50cnkgfSBmcm9tICcuLi9uZy1odHRwLWNhY2hpbmcuc2VydmljZSc7XHJcblxyXG5leHBvcnQgY2xhc3MgTmdIdHRwQ2FjaGluZ01lbW9yeVN0b3JhZ2UgaW1wbGVtZW50cyBOZ0h0dHBDYWNoaW5nU3RvcmFnZUludGVyZmFjZSB7XHJcblxyXG4gICAgZ2V0IHNpemUoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zdG9yZS5zaXplO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RvcmUgPSBuZXcgTWFwPHN0cmluZywgTmdIdHRwQ2FjaGluZ0VudHJ5PigpO1xyXG5cclxuICAgIGNsZWFyKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuc3RvcmUuY2xlYXIoKTtcclxuICAgIH1cclxuXHJcbiAgICBkZWxldGUoa2V5OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zdG9yZS5kZWxldGUoa2V5KTtcclxuICAgIH1cclxuXHJcbiAgICBmb3JFYWNoKGNhbGxiYWNrZm46ICh2YWx1ZTogTmdIdHRwQ2FjaGluZ0VudHJ5LCBrZXk6IHN0cmluZykgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JlLmZvckVhY2goY2FsbGJhY2tmbik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0KGtleTogc3RyaW5nKTogTmdIdHRwQ2FjaGluZ0VudHJ5IHwgdW5kZWZpbmVkIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zdG9yZS5nZXQoa2V5KTtcclxuICAgIH1cclxuXHJcbiAgICBoYXMoa2V5OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zdG9yZS5oYXMoa2V5KTtcclxuICAgIH1cclxuXHJcbiAgICBzZXQoa2V5OiBzdHJpbmcsIHZhbHVlOiBOZ0h0dHBDYWNoaW5nRW50cnkpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnN0b3JlLnNldChrZXksIHZhbHVlKTtcclxuICAgIH1cclxufVxyXG4iXX0=
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctaHR0cC1jYWNoaW5nLXN0b3JhZ2UuaW50ZXJmYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctaHR0cC1jYWNoaW5nL3NyYy9saWIvc3RvcmFnZS9uZy1odHRwLWNhY2hpbmctc3RvcmFnZS5pbnRlcmZhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nSHR0cENhY2hpbmdFbnRyeSB9IGZyb20gJy4uL25nLWh0dHAtY2FjaGluZy5zZXJ2aWNlJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTmdIdHRwQ2FjaGluZ1N0b3JhZ2VJbnRlcmZhY2Uge1xyXG5cclxuICAgIHJlYWRvbmx5IHNpemU6IG51bWJlcjtcclxuXHJcbiAgICBjbGVhcigpOiB2b2lkO1xyXG5cclxuICAgIGRlbGV0ZShrZXk6IHN0cmluZyk6IGJvb2xlYW47XHJcblxyXG4gICAgZm9yRWFjaChjYWxsYmFja2ZuOiAodmFsdWU6IE5nSHR0cENhY2hpbmdFbnRyeSwga2V5OiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkO1xyXG5cclxuICAgIGdldChrZXk6IHN0cmluZyk6IE5nSHR0cENhY2hpbmdFbnRyeSB8IHVuZGVmaW5lZDtcclxuXHJcbiAgICBoYXMoa2V5OiBzdHJpbmcpOiBib29sZWFuO1xyXG5cclxuICAgIHNldChrZXk6IHN0cmluZywgdmFsdWU6IE5nSHR0cENhY2hpbmdFbnRyeSk6IHZvaWQ7XHJcbn1cclxuIl19
@@ -1 +0,0 @@
1
- {"version":3,"file":"ng-http-caching.js","sources":["../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-memory-storage.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching-interceptor.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching.module.ts","../../../projects/ng-http-caching/src/public-api.ts","../../../projects/ng-http-caching/src/ng-http-caching.ts"],"sourcesContent":["import { NgHttpCachingStorageInterface } from './ng-http-caching-storage.interface';\r\nimport { NgHttpCachingEntry } from '../ng-http-caching.service';\r\n\r\nexport class NgHttpCachingMemoryStorage implements NgHttpCachingStorageInterface {\r\n\r\n get size(): number {\r\n return this.store.size;\r\n }\r\n\r\n private store = new Map<string, NgHttpCachingEntry>();\r\n\r\n clear(): void {\r\n this.store.clear();\r\n }\r\n\r\n delete(key: string): boolean {\r\n return this.store.delete(key);\r\n }\r\n\r\n forEach(callbackfn: (value: NgHttpCachingEntry, key: string) => void): void {\r\n return this.store.forEach(callbackfn);\r\n }\r\n\r\n get(key: string): NgHttpCachingEntry | undefined {\r\n return this.store.get(key);\r\n }\r\n\r\n has(key: string): boolean {\r\n return this.store.has(key);\r\n }\r\n\r\n set(key: string, value: NgHttpCachingEntry): void {\r\n this.store.set(key, value);\r\n }\r\n}\r\n","import { Injectable, InjectionToken, Inject, Optional } from '@angular/core';\r\nimport { HttpRequest, HttpResponse, HttpEvent } from '@angular/common/http';\r\nimport { Observable } from 'rxjs/internal/Observable';\r\nimport { NgHttpCachingStorageInterface } from './storage/ng-http-caching-storage.interface';\r\nimport { NgHttpCachingMemoryStorage } from './storage/ng-http-caching-memory-storage';\r\n\r\nexport interface NgHttpCachingEntry {\r\n url: string;\r\n response: HttpResponse<any>;\r\n request: HttpRequest<any>;\r\n addedTime: number;\r\n}\r\n\r\nexport const NG_HTTP_CACHING_CONFIG = new InjectionToken<NgHttpCachingConfig>(\r\n 'ng-http-caching.config'\r\n);\r\n\r\nexport enum NgHttpCachingStrategy {\r\n ALLOW_ALL = 'ALLOW_ALL',\r\n DISALLOW_ALL = 'DISALLOW_ALL',\r\n}\r\n\r\nexport enum NgHttpCachingHeaders {\r\n ALLOW_CACHE = 'X-NG-HTTP-CACHING-ALLOW-CACHE',\r\n DISALLOW_CACHE = 'X-NG-HTTP-CACHING-DISALLOW-CACHE',\r\n LIFETIME = 'X-NG-HTTP-CACHING-LIFETIME',\r\n TAG = 'X-NG-HTTP-CACHING-TAG',\r\n}\r\nexport class NgHttpCachingConfig {\r\n store?: NgHttpCachingStorageInterface;\r\n lifetime?: number;\r\n allowedMethod?: string[];\r\n cacheStrategy?: NgHttpCachingStrategy;\r\n isExpired?: (entry: NgHttpCachingEntry) => boolean | undefined;\r\n isCacheable?: (req: HttpRequest<any>) => boolean | undefined;\r\n getKey?: (req: HttpRequest<any>) => string | undefined;\r\n isValid?: (entry: NgHttpCachingEntry) => boolean | undefined;\r\n}\r\n\r\nexport const NgHttpCachingConfigDefault: NgHttpCachingConfig = {\r\n store: new NgHttpCachingMemoryStorage(),\r\n lifetime: 60 * 60 * 100,\r\n allowedMethod: ['GET'],\r\n cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,\r\n};\r\n\r\n@Injectable()\r\nexport class NgHttpCachingService {\r\n\r\n private queue = new Map<string, Observable<HttpEvent<any>>>();\r\n\r\n private config: NgHttpCachingConfig;\r\n\r\n constructor(\r\n @Inject(NG_HTTP_CACHING_CONFIG) @Optional() config: NgHttpCachingConfig\r\n ) {\r\n if (config) {\r\n this.config = { ...NgHttpCachingConfigDefault, ...config };\r\n } else {\r\n this.config = NgHttpCachingConfigDefault;\r\n }\r\n }\r\n\r\n /**\r\n * Return the config\r\n */\r\n getConfig(): NgHttpCachingConfig {\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Return the queue map\r\n */\r\n getQueue(): Map<string, Observable<HttpEvent<any>>> {\r\n return this.queue;\r\n }\r\n\r\n /**\r\n * Return the cache store\r\n */\r\n getStore(): NgHttpCachingStorageInterface {\r\n return this.config.store;\r\n }\r\n\r\n /**\r\n * Return response from cache\r\n */\r\n getFromCache(req: HttpRequest<any>): HttpResponse<any> | undefined {\r\n const key: string = this.getKey(req);\r\n const cached: NgHttpCachingEntry = this.config.store.get(key);\r\n\r\n if (!cached) {\r\n return undefined;\r\n }\r\n\r\n if (this.isExpired(cached)) {\r\n this.clearCacheByKey(key);\r\n return undefined;\r\n }\r\n\r\n return cached.response;\r\n }\r\n\r\n /**\r\n * Add response to cache\r\n */\r\n addToCache(req: HttpRequest<any>, res: HttpResponse<any>): boolean {\r\n const key: string = this.getKey(req);\r\n const entry: NgHttpCachingEntry = {\r\n url: req.urlWithParams,\r\n response: res,\r\n request: req,\r\n addedTime: Date.now(),\r\n };\r\n if ( this.isValid(entry) ) {\r\n this.config.store.set(key, entry);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Delete response from cache\r\n */\r\n deleteFromCache(req: HttpRequest<any>): boolean {\r\n const key: string = this.getKey(req);\r\n return this.clearCacheByKey(key);\r\n }\r\n\r\n /**\r\n * Clear the cache\r\n */\r\n clearCache(): void {\r\n this.config.store.clear();\r\n }\r\n\r\n /**\r\n * Clear the cache by key\r\n */\r\n clearCacheByKey(key: string): boolean {\r\n return this.config.store.delete(key);\r\n }\r\n\r\n /**\r\n * Clear the cache by regex\r\n */\r\n clearCacheByRegex(regex: RegExp): void {\r\n this.config.store.forEach((entry: NgHttpCachingEntry, key: string) => {\r\n if ( regex.test(key) ){\r\n this.clearCacheByKey(key);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Clear the cache by TAG\r\n */\r\n clearCacheByTag(tag: string): void {\r\n this.config.store.forEach((entry: NgHttpCachingEntry, key: string) => {\r\n const tagHeader = entry.request.headers.get(NgHttpCachingHeaders.TAG);\r\n if ( tagHeader && tagHeader.split(',').includes(tag) ){\r\n this.clearCacheByKey(key);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Run garbage collector (delete expired cache entry)\r\n */\r\n runGc(): void {\r\n this.config.store.forEach((entry: NgHttpCachingEntry, key: string) => {\r\n if ( this.isExpired(entry) ){\r\n this.clearCacheByKey(key);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Return true if cache entry is expired\r\n */\r\n isExpired(entry: NgHttpCachingEntry): boolean {\r\n // if user provide custom method, use it\r\n if (typeof this.config.isExpired === 'function') {\r\n const result = this.config.isExpired(entry);\r\n // if result is undefined, normal behaviour is provided\r\n if (typeof result !== 'undefined') {\r\n return result;\r\n }\r\n }\r\n // config/default lifetime\r\n let lifetime = this.config.lifetime;\r\n // request has own lifetime\r\n if (entry.request.headers.has(NgHttpCachingHeaders.LIFETIME)) {\r\n lifetime = +entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);\r\n }\r\n // never expire if 0\r\n if (lifetime === 0) {\r\n return false;\r\n }\r\n // wrong lifetime\r\n if (lifetime < 0) {\r\n throw new Error('lifetime must be greater than or equal 0');\r\n }\r\n return entry.addedTime + lifetime < Date.now();\r\n }\r\n\r\n /**\r\n * Return true if cache entry is valid for store in the cache\r\n */\r\n isValid(entry: NgHttpCachingEntry): boolean {\r\n // if user provide custom method, use it\r\n if (typeof this.config.isValid === 'function') {\r\n const result = this.config.isValid(entry);\r\n // if result is undefined, normal behaviour is provided\r\n if (typeof result !== 'undefined') {\r\n return result;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Return true if the request is cacheable\r\n */\r\n isCacheable(req: HttpRequest<any>): boolean {\r\n // if user provide custom method, use it\r\n if (typeof this.config.isCacheable === 'function') {\r\n const result = this.config.isCacheable(req);\r\n // if result is undefined, normal behaviour is provided\r\n if (typeof result !== 'undefined') {\r\n return result;\r\n }\r\n }\r\n // request has disallow cache header\r\n if (req.headers.has(NgHttpCachingHeaders.DISALLOW_CACHE)) {\r\n return false;\r\n }\r\n // strategy is disallow all...\r\n if (this.config.cacheStrategy === NgHttpCachingStrategy.DISALLOW_ALL) {\r\n // request isn't allowed if come without allow header\r\n if (!req.headers.has(NgHttpCachingHeaders.ALLOW_CACHE)) {\r\n return false;\r\n }\r\n }\r\n // if allowed method is only ALL, allow all http methos\r\n if ( this.config.allowedMethod.length === 1) {\r\n if (this.config.allowedMethod[0] === 'ALL'){\r\n return true;\r\n }\r\n }\r\n // request is allowed if method is in allowedMethod\r\n return this.config.allowedMethod.indexOf(req.method) !== -1;\r\n }\r\n\r\n /**\r\n * Return the cache key\r\n */\r\n getKey(req: HttpRequest<any>): string {\r\n // if user provide custom method, use it\r\n if (typeof this.config.getKey === 'function') {\r\n const result = this.config.getKey(req);\r\n // if result is undefined, normal behaviour is provided\r\n if (typeof result !== 'undefined') {\r\n return result;\r\n }\r\n }\r\n // default key id is url with query parameters\r\n return req.urlWithParams;\r\n }\r\n\r\n /**\r\n * Return observable from cache\r\n */\r\n getFromQueue(req: HttpRequest<any>): Observable<HttpEvent<any>> | undefined {\r\n const key: string = this.getKey(req);\r\n const cached: Observable<HttpEvent<any>> = this.queue.get(key);\r\n\r\n if (!cached) {\r\n return undefined;\r\n }\r\n\r\n return cached;\r\n }\r\n\r\n /**\r\n * Add observable to cache\r\n */\r\n addToQueue(req: HttpRequest<any>, obs: Observable<HttpEvent<any>>): void {\r\n const key: string = this.getKey(req);\r\n this.queue.set(key, obs);\r\n }\r\n\r\n /**\r\n * Delete observable from cache\r\n */\r\n deleteFromQueue(req: HttpRequest<any>): boolean {\r\n const key: string = this.getKey(req);\r\n return this.queue.delete(key);\r\n }\r\n}\r\n","import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport { tap, finalize, share } from 'rxjs/operators';\nimport { NgHttpCachingService, NgHttpCachingHeaders } from './ng-http-caching.service';\n\n\n@Injectable()\nexport class NgHttpCachingInterceptorService implements HttpInterceptor {\n\n constructor(private readonly cacheService: NgHttpCachingService) {}\n\n intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n // run garbage collector\n this.cacheService.runGc();\n\n // Don't cache if it's not cacheable\n if ( !this.cacheService.isCacheable(req) ) {\n return this.sendRequest(req, next);\n }\n\n // Checked if there is pending response for this request\n const cachedObservable: Observable<HttpEvent<any>> = this.cacheService.getFromQueue(req);\n if ( cachedObservable ) {\n // console.log('cachedObservable', req);\n return cachedObservable;\n }\n\n // Checked if there is cached response for this request\n const cachedResponse: HttpResponse<any> = this.cacheService.getFromCache(req);\n if (cachedResponse) {\n // console.log('cachedResponse', req);\n return of(cachedResponse.clone());\n }\n\n // If the request of going through for first time\n // then let the request proceed and cache the response\n // console.log('sendRequest', req);\n const shared = this.sendRequest(req, next).pipe(\n tap(event => {\n if (event instanceof HttpResponse) {\n this.cacheService.addToCache(req, event.clone());\n }\n }),\n finalize(() => {\n // delete pending request\n this.cacheService.deleteFromQueue(req);\n }),\n share()\n );\n\n // add pending request to queue for cache parallell request\n this.cacheService.addToQueue(req, shared);\n\n return shared;\n }\n\n /**\n * Send http request (next handler)\n */\n sendRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n let cloned: HttpRequest<any> = req.clone();\n // trim custom headers before send request\n Object.values(NgHttpCachingHeaders).forEach(ngHttpCachingHeaders => {\n if ( cloned.headers.has(ngHttpCachingHeaders) ) {\n cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });\n }\n });\n return next.handle(cloned);\n }\n}\n","import { NgModule, ModuleWithProviders } from '@angular/core';\r\nimport { HTTP_INTERCEPTORS } from '@angular/common/http';\r\nimport {\r\n NG_HTTP_CACHING_CONFIG,\r\n NgHttpCachingConfig,\r\n NgHttpCachingService,\r\n} from './ng-http-caching.service';\r\nimport { NgHttpCachingInterceptorService } from './ng-http-caching-interceptor.service';\r\n\r\n@NgModule({\r\n declarations: [],\r\n imports: [],\r\n providers: [\r\n NgHttpCachingService,\r\n {\r\n provide: HTTP_INTERCEPTORS,\r\n useClass: NgHttpCachingInterceptorService,\r\n multi: true,\r\n },\r\n ],\r\n exports: [],\r\n})\r\nexport class NgHttpCachingModule {\r\n static forRoot(\r\n ngHttpCachingConfig?: NgHttpCachingConfig\r\n ): ModuleWithProviders<NgHttpCachingModule> {\r\n return {\r\n ngModule: NgHttpCachingModule,\r\n providers: [\r\n {\r\n provide: NG_HTTP_CACHING_CONFIG,\r\n useValue: ngHttpCachingConfig,\r\n },\r\n ],\r\n };\r\n }\r\n}\r\n","/*\r\n * Public API Surface of ng-http-caching\r\n */\r\n\r\nexport * from './lib/ng-http-caching-interceptor.service';\r\nexport * from './lib/ng-http-caching.service';\r\nexport * from './lib/ng-http-caching.module';\r\nexport * from './lib/storage/ng-http-caching-storage.interface';\r\nexport * from './lib/storage/ng-http-caching-memory-storage';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}