ng-http-caching 15.0.3 → 15.2.2
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.
- package/README.md +1 -1
- package/esm2020/lib/ng-http-caching-interceptor.service.mjs +8 -9
- package/esm2020/lib/ng-http-caching.module.mjs +4 -4
- package/esm2020/lib/ng-http-caching.service.mjs +60 -13
- package/esm2020/lib/storage/ng-http-caching-browser-storage.mjs +10 -11
- package/esm2020/lib/storage/ng-http-caching-memory-storage.mjs +1 -1
- package/esm2020/lib/storage/ng-http-caching-storage.interface.mjs +1 -1
- package/fesm2015/ng-http-caching.mjs +79 -34
- package/fesm2015/ng-http-caching.mjs.map +1 -1
- package/fesm2020/ng-http-caching.mjs +79 -34
- package/fesm2020/ng-http-caching.mjs.map +1 -1
- package/lib/ng-http-caching.service.d.ts +92 -9
- package/lib/storage/ng-http-caching-browser-storage.d.ts +5 -5
- package/lib/storage/ng-http-caching-memory-storage.d.ts +1 -1
- package/lib/storage/ng-http-caching-storage.interface.d.ts +22 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HttpResponse, HTTP_INTERCEPTORS, HttpHeaders, HttpParams, HttpRequest } from '@angular/common/http';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { InjectionToken, VERSION, Injectable, Inject, Optional, NgModule } from '@angular/core';
|
|
3
|
+
import { InjectionToken, VERSION, isDevMode, Injectable, Inject, Optional, NgModule } from '@angular/core';
|
|
4
4
|
import { scheduled, asapScheduler } from 'rxjs';
|
|
5
5
|
import { tap, finalize, share } from 'rxjs/operators';
|
|
6
6
|
|
|
@@ -34,14 +34,33 @@ class NgHttpCachingMemoryStorage {
|
|
|
34
34
|
const NG_HTTP_CACHING_CONFIG = new InjectionToken('ng-http-caching.config');
|
|
35
35
|
var NgHttpCachingStrategy;
|
|
36
36
|
(function (NgHttpCachingStrategy) {
|
|
37
|
+
/**
|
|
38
|
+
* All request are cacheable if HTTP method is into `allowedMethod`
|
|
39
|
+
*/
|
|
37
40
|
NgHttpCachingStrategy["ALLOW_ALL"] = "ALLOW_ALL";
|
|
41
|
+
/**
|
|
42
|
+
* Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`
|
|
43
|
+
*/
|
|
38
44
|
NgHttpCachingStrategy["DISALLOW_ALL"] = "DISALLOW_ALL";
|
|
39
45
|
})(NgHttpCachingStrategy || (NgHttpCachingStrategy = {}));
|
|
40
46
|
var NgHttpCachingHeaders;
|
|
41
47
|
(function (NgHttpCachingHeaders) {
|
|
48
|
+
/**
|
|
49
|
+
* Request is cacheable if HTTP method is into `allowedMethod`
|
|
50
|
+
*/
|
|
42
51
|
NgHttpCachingHeaders["ALLOW_CACHE"] = "X-NG-HTTP-CACHING-ALLOW-CACHE";
|
|
52
|
+
/**
|
|
53
|
+
* Request isn't cacheable
|
|
54
|
+
*/
|
|
43
55
|
NgHttpCachingHeaders["DISALLOW_CACHE"] = "X-NG-HTTP-CACHING-DISALLOW-CACHE";
|
|
56
|
+
/**
|
|
57
|
+
* Specific cache lifetime for the request
|
|
58
|
+
*/
|
|
44
59
|
NgHttpCachingHeaders["LIFETIME"] = "X-NG-HTTP-CACHING-LIFETIME";
|
|
60
|
+
/**
|
|
61
|
+
* You can tag multiple request by adding this header with the same tag and
|
|
62
|
+
* using `NgHttpCachingService.clearCacheByTag(tag: string)` for delete all the tagged request
|
|
63
|
+
*/
|
|
45
64
|
NgHttpCachingHeaders["TAG"] = "X-NG-HTTP-CACHING-TAG";
|
|
46
65
|
})(NgHttpCachingHeaders || (NgHttpCachingHeaders = {}));
|
|
47
66
|
const NgHttpCachingHeadersList = Object.values(NgHttpCachingHeaders);
|
|
@@ -56,13 +75,14 @@ const NgHttpCachingConfigDefault = {
|
|
|
56
75
|
store: new NgHttpCachingMemoryStorage(),
|
|
57
76
|
lifetime: NG_HTTP_CACHING_HOUR_IN_MS,
|
|
58
77
|
version: VERSION.major,
|
|
59
|
-
allowedMethod: ['GET'],
|
|
78
|
+
allowedMethod: ['GET', 'HEAD'],
|
|
60
79
|
cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,
|
|
61
80
|
};
|
|
62
81
|
class NgHttpCachingService {
|
|
63
82
|
constructor(config) {
|
|
64
83
|
this.queue = new Map();
|
|
65
84
|
this.gcLock = false;
|
|
85
|
+
this.devMode = isDevMode();
|
|
66
86
|
if (config) {
|
|
67
87
|
this.config = Object.assign(Object.assign({}, NgHttpCachingConfigDefault), config);
|
|
68
88
|
}
|
|
@@ -103,13 +123,12 @@ class NgHttpCachingService {
|
|
|
103
123
|
this.clearCacheByKey(key);
|
|
104
124
|
return undefined;
|
|
105
125
|
}
|
|
106
|
-
return cached.response;
|
|
126
|
+
return this.deepFreeze(cached.response);
|
|
107
127
|
}
|
|
108
128
|
/**
|
|
109
129
|
* Add response to cache
|
|
110
130
|
*/
|
|
111
131
|
addToCache(req, res) {
|
|
112
|
-
const key = this.getKey(req);
|
|
113
132
|
const entry = {
|
|
114
133
|
url: req.urlWithParams,
|
|
115
134
|
response: res,
|
|
@@ -118,6 +137,7 @@ class NgHttpCachingService {
|
|
|
118
137
|
version: this.config.version,
|
|
119
138
|
};
|
|
120
139
|
if (this.isValid(entry)) {
|
|
140
|
+
const key = this.getKey(req);
|
|
121
141
|
this.config.store.set(key, entry);
|
|
122
142
|
return true;
|
|
123
143
|
}
|
|
@@ -146,7 +166,7 @@ class NgHttpCachingService {
|
|
|
146
166
|
* Clear the cache by regex
|
|
147
167
|
*/
|
|
148
168
|
clearCacheByRegex(regex) {
|
|
149
|
-
this.config.store.forEach((
|
|
169
|
+
this.config.store.forEach((_, key) => {
|
|
150
170
|
if (regex.test(key)) {
|
|
151
171
|
this.clearCacheByKey(key);
|
|
152
172
|
}
|
|
@@ -203,7 +223,7 @@ class NgHttpCachingService {
|
|
|
203
223
|
return false;
|
|
204
224
|
}
|
|
205
225
|
// wrong lifetime
|
|
206
|
-
if (lifetime < 0) {
|
|
226
|
+
if (lifetime < 0 || isNaN(lifetime)) {
|
|
207
227
|
throw new Error('lifetime must be greater than or equal 0');
|
|
208
228
|
}
|
|
209
229
|
return entry.addedTime + lifetime < Date.now();
|
|
@@ -259,7 +279,9 @@ class NgHttpCachingService {
|
|
|
259
279
|
return this.config.allowedMethod.indexOf(req.method) !== -1;
|
|
260
280
|
}
|
|
261
281
|
/**
|
|
262
|
-
* Return the cache key
|
|
282
|
+
* Return the cache key.
|
|
283
|
+
* Default key is http method plus url with query parameters, eg.:
|
|
284
|
+
* `GET@https://github.com/nigrosimone/ng-http-caching`
|
|
263
285
|
*/
|
|
264
286
|
getKey(req) {
|
|
265
287
|
// if user provide custom method, use it
|
|
@@ -270,8 +292,8 @@ class NgHttpCachingService {
|
|
|
270
292
|
return result;
|
|
271
293
|
}
|
|
272
294
|
}
|
|
273
|
-
// default key
|
|
274
|
-
return req.urlWithParams;
|
|
295
|
+
// default key is req.method plus url with query parameters
|
|
296
|
+
return req.method + '@' + req.urlWithParams;
|
|
275
297
|
}
|
|
276
298
|
/**
|
|
277
299
|
* Return observable from cache
|
|
@@ -298,10 +320,35 @@ class NgHttpCachingService {
|
|
|
298
320
|
const key = this.getKey(req);
|
|
299
321
|
return this.queue.delete(key);
|
|
300
322
|
}
|
|
323
|
+
/**
|
|
324
|
+
* Recursively Object.freeze simple Javascript structures consisting of plain objects, arrays, and primitives.
|
|
325
|
+
* Make the data immutable.
|
|
326
|
+
* @returns immutable object
|
|
327
|
+
*/
|
|
328
|
+
deepFreeze(object) {
|
|
329
|
+
// No freezing in production (for better performance).
|
|
330
|
+
if (!this.devMode || !object || typeof object !== 'object') {
|
|
331
|
+
return object;
|
|
332
|
+
}
|
|
333
|
+
// When already frozen, we assume its children are frozen (for better performance).
|
|
334
|
+
// This should be true if you always use `deepFreeze` to freeze objects.
|
|
335
|
+
//
|
|
336
|
+
// Note that Object.isFrozen will also return `true` for primitives (numbers,
|
|
337
|
+
// strings, booleans, undefined, null), so there is no need to check for
|
|
338
|
+
// those explicitly.
|
|
339
|
+
if (Object.isFrozen(object)) {
|
|
340
|
+
return object;
|
|
341
|
+
}
|
|
342
|
+
// At this point we know that we're dealing with either an array or plain object, so
|
|
343
|
+
// just freeze it and recurse on its values.
|
|
344
|
+
Object.freeze(object);
|
|
345
|
+
Object.keys(object).forEach(key => this.deepFreeze(object[key]));
|
|
346
|
+
return object;
|
|
347
|
+
}
|
|
301
348
|
}
|
|
302
|
-
NgHttpCachingService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
303
|
-
NgHttpCachingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.
|
|
304
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
349
|
+
NgHttpCachingService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingService, deps: [{ token: NG_HTTP_CACHING_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
350
|
+
NgHttpCachingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingService });
|
|
351
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingService, decorators: [{
|
|
305
352
|
type: Injectable
|
|
306
353
|
}], ctorParameters: function () {
|
|
307
354
|
return [{ type: undefined, decorators: [{
|
|
@@ -314,10 +361,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImpor
|
|
|
314
361
|
|
|
315
362
|
/**
|
|
316
363
|
* Fix for https://github.com/ReactiveX/rxjs/issues/7241
|
|
317
|
-
* @param response HttpResponse<any>
|
|
318
364
|
*/
|
|
319
|
-
function* _of(
|
|
320
|
-
yield
|
|
365
|
+
function* _of(value) {
|
|
366
|
+
yield value;
|
|
321
367
|
}
|
|
322
368
|
class NgHttpCachingInterceptorService {
|
|
323
369
|
constructor(cacheService) {
|
|
@@ -333,13 +379,13 @@ class NgHttpCachingInterceptorService {
|
|
|
333
379
|
// Checked if there is pending response for this request
|
|
334
380
|
const cachedObservable = this.cacheService.getFromQueue(req);
|
|
335
381
|
if (cachedObservable) {
|
|
336
|
-
// console.log('cachedObservable'
|
|
382
|
+
// console.log('cachedObservable');
|
|
337
383
|
return scheduled(cachedObservable, asapScheduler);
|
|
338
384
|
}
|
|
339
385
|
// Checked if there is cached response for this request
|
|
340
386
|
const cachedResponse = this.cacheService.getFromCache(req);
|
|
341
387
|
if (cachedResponse) {
|
|
342
|
-
// console.log('cachedResponse'
|
|
388
|
+
// console.log('cachedResponse');
|
|
343
389
|
return scheduled(_of(cachedResponse.clone()), asapScheduler);
|
|
344
390
|
}
|
|
345
391
|
// If the request of going through for first time
|
|
@@ -371,9 +417,9 @@ class NgHttpCachingInterceptorService {
|
|
|
371
417
|
return next.handle(cloned);
|
|
372
418
|
}
|
|
373
419
|
}
|
|
374
|
-
NgHttpCachingInterceptorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
375
|
-
NgHttpCachingInterceptorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.
|
|
376
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
420
|
+
NgHttpCachingInterceptorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingInterceptorService, deps: [{ token: NgHttpCachingService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
421
|
+
NgHttpCachingInterceptorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingInterceptorService });
|
|
422
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingInterceptorService, decorators: [{
|
|
377
423
|
type: Injectable
|
|
378
424
|
}], ctorParameters: function () { return [{ type: NgHttpCachingService }]; } });
|
|
379
425
|
|
|
@@ -390,9 +436,9 @@ class NgHttpCachingModule {
|
|
|
390
436
|
};
|
|
391
437
|
}
|
|
392
438
|
}
|
|
393
|
-
NgHttpCachingModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.
|
|
394
|
-
NgHttpCachingModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.
|
|
395
|
-
NgHttpCachingModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.
|
|
439
|
+
NgHttpCachingModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
440
|
+
NgHttpCachingModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingModule });
|
|
441
|
+
NgHttpCachingModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingModule, providers: [
|
|
396
442
|
NgHttpCachingService,
|
|
397
443
|
{
|
|
398
444
|
provide: HTTP_INTERCEPTORS,
|
|
@@ -400,7 +446,7 @@ NgHttpCachingModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", ver
|
|
|
400
446
|
multi: true,
|
|
401
447
|
},
|
|
402
448
|
] });
|
|
403
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.
|
|
449
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingModule, decorators: [{
|
|
404
450
|
type: NgModule,
|
|
405
451
|
args: [{
|
|
406
452
|
providers: [
|
|
@@ -415,7 +461,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImpor
|
|
|
415
461
|
}] });
|
|
416
462
|
|
|
417
463
|
const KEY_PREFIX = 'NgHttpCaching::';
|
|
418
|
-
|
|
464
|
+
const serializeRequest = (req) => {
|
|
419
465
|
const request = req.clone(); // Make a clone, useful for doing destructive things
|
|
420
466
|
return JSON.stringify({
|
|
421
467
|
headers: Object.fromEntries(// Just a helper to make this into an object, not really required but makes the output nicer
|
|
@@ -432,8 +478,8 @@ function serializeRequest(req) {
|
|
|
432
478
|
respnseType: request.responseType,
|
|
433
479
|
body: request.serializeBody() // Serialize the body, all well and good since we are working on a clone
|
|
434
480
|
});
|
|
435
|
-
}
|
|
436
|
-
|
|
481
|
+
};
|
|
482
|
+
const serializeResponse = (res) => {
|
|
437
483
|
const response = res.clone();
|
|
438
484
|
return JSON.stringify({
|
|
439
485
|
headers: Object.fromEntries(// Just a helper to make this into an object, not really required but makes the output nicer
|
|
@@ -443,14 +489,13 @@ function serializeResponse(res) {
|
|
|
443
489
|
status: response.status,
|
|
444
490
|
statusText: response.statusText,
|
|
445
491
|
url: response.url,
|
|
446
|
-
body: response // Serialize the body, all well and good since we are working on a clone
|
|
492
|
+
body: response.body // Serialize the body, all well and good since we are working on a clone
|
|
447
493
|
});
|
|
448
|
-
}
|
|
449
|
-
|
|
494
|
+
};
|
|
495
|
+
const deserializeRequest = (req) => {
|
|
450
496
|
const request = JSON.parse(req);
|
|
451
497
|
const headers = new HttpHeaders(request.headers);
|
|
452
498
|
const params = new HttpParams(); // Probably some way to make this a one-liner, but alas, there are no good docs
|
|
453
|
-
// tslint:disable-next-line: forin
|
|
454
499
|
for (const parameter in request.params) {
|
|
455
500
|
request.params[parameter].forEach((paramValue) => params.append(parameter, paramValue));
|
|
456
501
|
}
|
|
@@ -460,8 +505,8 @@ function deserializeRequest(req) {
|
|
|
460
505
|
responseType: request.responseType,
|
|
461
506
|
withCredentials: request.withCredentials
|
|
462
507
|
});
|
|
463
|
-
}
|
|
464
|
-
|
|
508
|
+
};
|
|
509
|
+
const deserializeResponse = (res) => {
|
|
465
510
|
const response = JSON.parse(res);
|
|
466
511
|
return new HttpResponse({
|
|
467
512
|
url: response.url,
|
|
@@ -470,7 +515,7 @@ function deserializeResponse(res) {
|
|
|
470
515
|
status: response.status,
|
|
471
516
|
statusText: response.statusText,
|
|
472
517
|
});
|
|
473
|
-
}
|
|
518
|
+
};
|
|
474
519
|
class NgHttpCachingBrowserStorage {
|
|
475
520
|
constructor(storage) {
|
|
476
521
|
this.storage = storage;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-http-caching.mjs","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/lib/storage/ng-http-caching-browser-storage.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-local-storage.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-session-storage.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<any, any>>();\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\r\n forEach<K, T>(callbackfn: (value: NgHttpCachingEntry<K, T>, key: string) => void): void {\r\n return this.store.forEach(callbackfn);\r\n }\r\n\r\n get<K, T>(key: string): NgHttpCachingEntry<K, T> | 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<K, T>(key: string, value: NgHttpCachingEntry<K, T>): void {\r\n this.store.set(key, value);\r\n }\r\n}\r\n","import { Injectable, InjectionToken, Inject, Optional, VERSION } 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<K = any, T = any> {\r\n url: string;\r\n response: HttpResponse<T>;\r\n request: HttpRequest<K>;\r\n addedTime: number;\r\n version: string;\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\n\r\nexport const NgHttpCachingHeadersList = Object.values(NgHttpCachingHeaders);\r\n\r\nexport const NG_HTTP_CACHING_SECOND_IN_MS = 1000;\r\nexport const NG_HTTP_CACHING_MINUTE_IN_MS = NG_HTTP_CACHING_SECOND_IN_MS * 60;\r\nexport const NG_HTTP_CACHING_HOUR_IN_MS = NG_HTTP_CACHING_MINUTE_IN_MS * 60;\r\nexport const NG_HTTP_CACHING_DAY_IN_MS = NG_HTTP_CACHING_HOUR_IN_MS * 24;\r\nexport const NG_HTTP_CACHING_WEEK_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 7;\r\nexport const NG_HTTP_CACHING_MONTH_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 30;\r\nexport const NG_HTTP_CACHING_YEAR_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 365;\r\n\r\nexport interface NgHttpCachingConfig {\r\n store?: NgHttpCachingStorageInterface;\r\n lifetime?: number;\r\n allowedMethod?: string[];\r\n cacheStrategy?: NgHttpCachingStrategy;\r\n version?: string;\r\n isExpired?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined;\r\n isCacheable?: <K>(req: HttpRequest<K>) => boolean | undefined;\r\n getKey?: <K>(req: HttpRequest<K>) => string | undefined;\r\n isValid?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined;\r\n}\r\n\r\nexport interface NgHttpCachingDefaultConfig extends NgHttpCachingConfig {\r\n store: NgHttpCachingStorageInterface;\r\n lifetime: number;\r\n allowedMethod: string[];\r\n cacheStrategy: NgHttpCachingStrategy;\r\n version: string;\r\n}\r\n\r\nexport const NgHttpCachingConfigDefault: NgHttpCachingDefaultConfig = {\r\n store: new NgHttpCachingMemoryStorage(),\r\n lifetime: NG_HTTP_CACHING_HOUR_IN_MS,\r\n version: VERSION.major,\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: NgHttpCachingDefaultConfig;\r\n\r\n private gcLock = false;\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 // start cache clean\r\n this.runGc();\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<K, T>(req: HttpRequest<K>): HttpResponse<T> | undefined {\r\n const key: string = this.getKey(req);\r\n const cached: NgHttpCachingEntry<K, T> | undefined = this.config.store.get<K, T>(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<K, T>(req: HttpRequest<K>, res: HttpResponse<T>): boolean {\r\n const key: string = this.getKey(req);\r\n const entry: NgHttpCachingEntry<K, T> = {\r\n url: req.urlWithParams,\r\n response: res,\r\n request: req,\r\n addedTime: Date.now(),\r\n version: this.config.version,\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<K>(req: HttpRequest<K>): 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<K, T>(regex: RegExp): void {\r\n this.config.store.forEach<K, T>((entry: NgHttpCachingEntry<K, T>, 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<K, T>(tag: string): void {\r\n this.config.store.forEach<K, T>((entry: NgHttpCachingEntry<K, T>, 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<K, T>(): boolean {\r\n if (this.gcLock) {\r\n return false;\r\n }\r\n this.gcLock = true;\r\n this.config.store.forEach<K, T>((entry: NgHttpCachingEntry<K, T>, key: string) => {\r\n if (this.isExpired(entry)) {\r\n this.clearCacheByKey(key);\r\n }\r\n });\r\n this.gcLock = false;\r\n return true;\r\n }\r\n\r\n /**\r\n * Return true if cache entry is expired\r\n */\r\n isExpired<K, T>(entry: NgHttpCachingEntry<K, T>): 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 (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // config/default lifetime\r\n let lifetime: number = this.config.lifetime;\r\n // request has own lifetime\r\n const headerLifetime = entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);\r\n if (headerLifetime) {\r\n lifetime = +headerLifetime;\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<K, T>(entry: NgHttpCachingEntry<K, T>): 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 (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // different version\r\n if (this.config.version !== entry.version) {\r\n return false;\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<K>(req: HttpRequest<K>): 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 (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<K>(req: HttpRequest<K>): 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 (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<K, T>(req: HttpRequest<K>): Observable<HttpEvent<T>> | undefined {\r\n const key: string = this.getKey(req);\r\n const cached: Observable<HttpEvent<T>> | undefined = 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<K, T>(req: HttpRequest<K>, obs: Observable<HttpEvent<T>>): 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<K>(req: HttpRequest<K>): 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';\r\nimport { Injectable } from '@angular/core';\r\nimport { asapScheduler, Observable, scheduled } from 'rxjs';\r\nimport { tap, finalize, share } from 'rxjs/operators';\r\nimport { NgHttpCachingService, NgHttpCachingHeadersList } from './ng-http-caching.service';\r\n\r\n/**\r\n * Fix for https://github.com/ReactiveX/rxjs/issues/7241\r\n * @param response HttpResponse<any>\r\n */\r\nfunction* _of(response: HttpResponse<any>) {\r\n yield response;\r\n}\r\n\r\n@Injectable()\r\nexport class NgHttpCachingInterceptorService implements HttpInterceptor {\r\n\r\n\r\n constructor(private readonly cacheService: NgHttpCachingService) { }\r\n\r\n intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n // run garbage collector\r\n this.cacheService.runGc();\r\n\r\n // Don't cache if it's not cacheable\r\n if (!this.cacheService.isCacheable(req)) {\r\n return this.sendRequest(req, next);\r\n }\r\n\r\n // Checked if there is pending response for this request\r\n const cachedObservable: Observable<HttpEvent<any>> | undefined = this.cacheService.getFromQueue(req);\r\n if (cachedObservable) {\r\n // console.log('cachedObservable', req);\r\n return scheduled(cachedObservable, asapScheduler);\r\n }\r\n\r\n // Checked if there is cached response for this request\r\n const cachedResponse: HttpResponse<any> | undefined = this.cacheService.getFromCache(req);\r\n if (cachedResponse) {\r\n // console.log('cachedResponse', req);\r\n\r\n return scheduled(_of(cachedResponse.clone()), asapScheduler);\r\n }\r\n\r\n // If the request of going through for first time\r\n // then let the request proceed and cache the response\r\n // console.log('sendRequest', req);\r\n const shared = this.sendRequest(req, next).pipe(\r\n tap(event => {\r\n if (event instanceof HttpResponse) {\r\n this.cacheService.addToCache(req, event.clone());\r\n }\r\n }),\r\n finalize(() => {\r\n // delete pending request\r\n this.cacheService.deleteFromQueue(req);\r\n }),\r\n share()\r\n );\r\n\r\n // add pending request to queue for cache parallell request\r\n this.cacheService.addToQueue(req, shared);\r\n\r\n return shared;\r\n }\r\n\r\n /**\r\n * Send http request (next handler)\r\n */\r\n sendRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n let cloned: HttpRequest<any> = req.clone();\r\n // trim custom headers before send request\r\n NgHttpCachingHeadersList.forEach(ngHttpCachingHeaders => {\r\n if (cloned.headers.has(ngHttpCachingHeaders)) {\r\n cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });\r\n }\r\n });\r\n return next.handle(cloned);\r\n }\r\n}\r\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 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})\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","import { NgHttpCachingStorageInterface } from './ng-http-caching-storage.interface';\r\nimport { NgHttpCachingEntry } from '../ng-http-caching.service';\r\nimport { HttpHeaders, HttpParams, HttpRequest, HttpResponse } from '@angular/common/http';\r\n\r\nconst KEY_PREFIX = 'NgHttpCaching::';\r\n\r\nexport function serializeRequest(req: HttpRequest<any>): string {\r\n const request = req.clone(); // Make a clone, useful for doing destructive things\r\n return JSON.stringify({\r\n headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n request.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ),\r\n method: request.method, // The Request Method, e.g. GET, POST, DELETE\r\n url: request.url, // The URL\r\n params: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n request.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ), // The request parameters\r\n withCredentials: request.withCredentials, // Whether credentials are being sent\r\n respnseType: request.responseType, // The response type\r\n body: request.serializeBody() // Serialize the body, all well and good since we are working on a clone\r\n });\r\n}\r\n\r\nexport function serializeResponse(res: HttpResponse<any>): string {\r\n const response = res.clone();\r\n return JSON.stringify({\r\n headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n response.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, response.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ),\r\n status: response.status,\r\n statusText: response.statusText,\r\n url: response.url,\r\n body: response // Serialize the body, all well and good since we are working on a clone\r\n });\r\n}\r\n\r\nexport function deserializeRequest<T = any>(req: string): HttpRequest<T> {\r\n const request = JSON.parse(req);\r\n const headers = new HttpHeaders(request.headers);\r\n const params = new HttpParams(); // Probably some way to make this a one-liner, but alas, there are no good docs\r\n // tslint:disable-next-line: forin\r\n for (const parameter in request.params) {\r\n request.params[parameter].forEach((paramValue: string) => params.append(parameter, paramValue));\r\n }\r\n return new HttpRequest(request.method, request.url, request.body, {\r\n headers,\r\n params,\r\n responseType: request.responseType,\r\n withCredentials: request.withCredentials\r\n });\r\n}\r\n\r\nexport function deserializeResponse<T = any>(res: string): HttpResponse<T> {\r\n const response = JSON.parse(res);\r\n return new HttpResponse<T>({\r\n url: response.url,\r\n headers: new HttpHeaders(response.headers),\r\n body: response.body,\r\n status: response.status,\r\n statusText: response.statusText,\r\n });\r\n}\r\n\r\nexport class NgHttpCachingBrowserStorage implements NgHttpCachingStorageInterface {\r\n\r\n\r\n constructor(private storage: Storage) { }\r\n\r\n get size(): number {\r\n let count = 0;\r\n for (let i = 0, e = this.storage.length; i < e; i++) {\r\n const key = this.storage.key(i);\r\n if (key && key.startsWith(KEY_PREFIX)) {\r\n count++;\r\n }\r\n }\r\n return count;\r\n }\r\n\r\n clear(): void {\r\n for (let i = 0, e = this.storage.length; i < e; i++) {\r\n const key = this.storage.key(i);\r\n if (key && key.startsWith(KEY_PREFIX)) {\r\n this.storage.removeItem(key);\r\n }\r\n }\r\n }\r\n\r\n delete(key: string): boolean {\r\n this.storage.removeItem(KEY_PREFIX + key);\r\n return true;\r\n }\r\n\r\n\r\n forEach(callbackfn: (value: NgHttpCachingEntry, key: string) => void): void {\r\n // iterate this.storage\r\n const lenPrefix = KEY_PREFIX.length;\r\n for (let i = 0, e = this.storage.length; i < e; i++) {\r\n const key = this.storage.key(i);\r\n if (key && key.startsWith(KEY_PREFIX)) {\r\n const value = this.get(key.substring(lenPrefix));\r\n if (value) {\r\n callbackfn(value, key);\r\n }\r\n }\r\n }\r\n }\r\n\r\n get(key: string): NgHttpCachingEntry | undefined {\r\n const item = this.storage.getItem(KEY_PREFIX + key);\r\n if (item) {\r\n const parsedItem: StorageEntry = JSON.parse(item);\r\n return {\r\n url: parsedItem.url,\r\n response: deserializeResponse(parsedItem.response),\r\n request: deserializeRequest(parsedItem.request),\r\n addedTime: parsedItem.addedTime,\r\n version: parsedItem.version\r\n };\r\n }\r\n return undefined;\r\n }\r\n\r\n has(key: string): boolean {\r\n return this.storage.getItem(KEY_PREFIX + key) !== undefined;\r\n }\r\n\r\n set(key: string, value: NgHttpCachingEntry): void {\r\n this.storage.setItem(KEY_PREFIX + key, JSON.stringify({\r\n url: value.url,\r\n response: serializeResponse(value.response),\r\n request: serializeRequest(value.request),\r\n addedTime: value.addedTime\r\n } as StorageEntry));\r\n }\r\n}\r\n\r\ninterface StorageEntry {\r\n url: string;\r\n response: string;\r\n request: string;\r\n addedTime: number;\r\n version: string;\r\n}\r\n","import { NgHttpCachingBrowserStorage } from './ng-http-caching-browser-storage';\r\n\r\nexport class NgHttpCachingLocalStorage extends NgHttpCachingBrowserStorage {\r\n\r\n constructor() {\r\n super(localStorage);\r\n }\r\n}\r\n","import { NgHttpCachingBrowserStorage } from './ng-http-caching-browser-storage';\r\n\r\nexport class NgHttpCachingSessionStorage extends NgHttpCachingBrowserStorage {\r\n\r\n constructor() {\r\n super(sessionStorage);\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\nexport * from './lib/storage/ng-http-caching-local-storage';\r\nexport * from './lib/storage/ng-http-caching-session-storage';\r\nexport * from './lib/storage/ng-http-caching-browser-storage';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.NgHttpCachingService"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ng-http-caching.mjs","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/lib/storage/ng-http-caching-browser-storage.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-local-storage.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-session-storage.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<any, any>>();\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<K, T>(callbackfn: (value: NgHttpCachingEntry<K, T>, key: string) => void): void {\r\n return this.store.forEach(callbackfn);\r\n }\r\n\r\n get<K, T>(key: string): Readonly<NgHttpCachingEntry<K, T>> | 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<K, T>(key: string, value: NgHttpCachingEntry<K, T>): void {\r\n this.store.set(key, value);\r\n }\r\n}\r\n","import { Injectable, InjectionToken, Inject, Optional, VERSION, isDevMode } 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<K = any, T = any> {\r\n /**\r\n * URL\r\n */\r\n url: string;\r\n /**\r\n * HttpResponse\r\n */\r\n response: HttpResponse<T>;\r\n /**\r\n * HttpRequest\r\n */\r\n request: HttpRequest<K>;\r\n /**\r\n * Timestam of add to cache time\r\n */\r\n addedTime: number;\r\n /**\r\n * Cache version\r\n */\r\n version: string;\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 /**\r\n * All request are cacheable if HTTP method is into `allowedMethod`\r\n */\r\n ALLOW_ALL = 'ALLOW_ALL',\r\n /**\r\n * Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`\r\n */\r\n DISALLOW_ALL = 'DISALLOW_ALL'\r\n}\r\n\r\nexport enum NgHttpCachingHeaders {\r\n /**\r\n * Request is cacheable if HTTP method is into `allowedMethod`\r\n */\r\n ALLOW_CACHE = 'X-NG-HTTP-CACHING-ALLOW-CACHE',\r\n /**\r\n * Request isn't cacheable\r\n */\r\n DISALLOW_CACHE = 'X-NG-HTTP-CACHING-DISALLOW-CACHE',\r\n /**\r\n * Specific cache lifetime for the request\r\n */\r\n LIFETIME = 'X-NG-HTTP-CACHING-LIFETIME',\r\n /**\r\n * You can tag multiple request by adding this header with the same tag and \r\n * using `NgHttpCachingService.clearCacheByTag(tag: string)` for delete all the tagged request\r\n */\r\n TAG = 'X-NG-HTTP-CACHING-TAG'\r\n}\r\n\r\nexport const NgHttpCachingHeadersList = Object.values(NgHttpCachingHeaders);\r\n\r\nexport const NG_HTTP_CACHING_SECOND_IN_MS = 1000;\r\nexport const NG_HTTP_CACHING_MINUTE_IN_MS = NG_HTTP_CACHING_SECOND_IN_MS * 60;\r\nexport const NG_HTTP_CACHING_HOUR_IN_MS = NG_HTTP_CACHING_MINUTE_IN_MS * 60;\r\nexport const NG_HTTP_CACHING_DAY_IN_MS = NG_HTTP_CACHING_HOUR_IN_MS * 24;\r\nexport const NG_HTTP_CACHING_WEEK_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 7;\r\nexport const NG_HTTP_CACHING_MONTH_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 30;\r\nexport const NG_HTTP_CACHING_YEAR_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 365;\r\n\r\nexport interface NgHttpCachingConfig {\r\n /**\r\n * Set the cache store. You can implement your custom store by implement the `NgHttpCachingStorageInterface` interface, eg.:\r\n */\r\n store?: NgHttpCachingStorageInterface;\r\n /**\r\n * Number of millisecond that a response is stored in the cache. \r\n * You can set specific \"lifetime\" for each request by add the header `X-NG-HTTP-CACHING-LIFETIME` (see example below).\r\n */\r\n lifetime?: number;\r\n /**\r\n * Array of allowed HTTP methods to cache. \r\n * You can allow multiple methods, eg.: `['GET', 'POST', 'PUT', 'DELETE', 'HEAD']` or \r\n * allow all methods by: `['ALL']`. If `allowedMethod` is an empty array (`[]`), no response are cached.\r\n * *Warning!* `NgHttpCaching` use the full url (url with query parameters) as unique key for the cached response,\r\n * this is correct for the `GET` request but is _potentially_ wrong for other type of request (eg. `POST`, `PUT`). \r\n * You can set a different \"key\" by customizing the `getKey` config method (see `getKey` section).\r\n */\r\n allowedMethod?: string[];\r\n /**\r\n * Set the cache strategy, possible strategies are:\r\n * - `NgHttpCachingStrategy.ALLOW_ALL`: All request are cacheable if HTTP method is into `allowedMethod`;\r\n * - `NgHttpCachingStrategy.DISALLOW_ALL`: Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`;\r\n */\r\n cacheStrategy?: NgHttpCachingStrategy;\r\n /**\r\n * Cache version. When you have a breaking change, change the version, and it'll delete the current cache automatically.\r\n * The default value is Angular major version (eg. 13), in this way, the cache is invalitaded on every Angular upgrade.\r\n */\r\n version?: string;\r\n /**\r\n * If this function return `true` the request is expired and a new request is send to backend, if return `false` isn't expired. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n isExpired?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined;\r\n /**\r\n * If this function return `true` the request is cacheable, if return `false` isn't cacheable. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n isCacheable?: <K>(req: HttpRequest<K>) => boolean | undefined;\r\n /**\r\n * This function return the unique key (`string`) for store the response into the cache. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n getKey?: <K>(req: HttpRequest<K>) => string | undefined;\r\n /**\r\n * If this function return `true` the cache entry is valid and can be strored, if return `false` isn't valid. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n isValid?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined;\r\n}\r\n\r\nexport interface NgHttpCachingDefaultConfig extends NgHttpCachingConfig {\r\n store: NgHttpCachingStorageInterface;\r\n lifetime: number;\r\n allowedMethod: string[];\r\n cacheStrategy: NgHttpCachingStrategy;\r\n version: string;\r\n}\r\n\r\nexport const NgHttpCachingConfigDefault: Readonly<NgHttpCachingDefaultConfig> = {\r\n store: new NgHttpCachingMemoryStorage(),\r\n lifetime: NG_HTTP_CACHING_HOUR_IN_MS,\r\n version: VERSION.major,\r\n allowedMethod: ['GET', 'HEAD'],\r\n cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,\r\n};\r\n\r\n@Injectable()\r\nexport class NgHttpCachingService {\r\n\r\n private readonly queue = new Map<string, Observable<HttpEvent<any>>>();\r\n\r\n private readonly config: NgHttpCachingDefaultConfig;\r\n\r\n private gcLock = false;\r\n\r\n private devMode: boolean = isDevMode();\r\n\r\n constructor(\r\n @Inject(NG_HTTP_CACHING_CONFIG) @Optional() config: Readonly<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 // start cache clean\r\n this.runGc();\r\n }\r\n\r\n /**\r\n * Return the config\r\n */\r\n getConfig(): Readonly<NgHttpCachingConfig> {\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Return the queue map\r\n */\r\n getQueue(): Readonly<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(): Readonly<NgHttpCachingStorageInterface> {\r\n return this.config.store;\r\n }\r\n\r\n /**\r\n * Return response from cache\r\n */\r\n getFromCache<K, T>(req: HttpRequest<K>): Readonly<HttpResponse<T>> | undefined {\r\n const key: string = this.getKey(req);\r\n const cached: NgHttpCachingEntry<K, T> | undefined = this.config.store.get<K, T>(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 this.deepFreeze(cached.response);\r\n }\r\n\r\n /**\r\n * Add response to cache\r\n */\r\n addToCache<K, T>(req: HttpRequest<K>, res: HttpResponse<T>): boolean {\r\n const entry: NgHttpCachingEntry<K, T> = {\r\n url: req.urlWithParams,\r\n response: res,\r\n request: req,\r\n addedTime: Date.now(),\r\n version: this.config.version,\r\n };\r\n if (this.isValid(entry)) {\r\n const key: string = this.getKey(req);\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<K>(req: HttpRequest<K>): 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<K, T>(regex: RegExp): void {\r\n this.config.store.forEach<K, T>((_: NgHttpCachingEntry<K, T>, 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<K, T>(tag: string): void {\r\n this.config.store.forEach<K, T>((entry: NgHttpCachingEntry<K, T>, 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<K, T>(): boolean {\r\n if (this.gcLock) {\r\n return false;\r\n }\r\n this.gcLock = true;\r\n this.config.store.forEach<K, T>((entry: NgHttpCachingEntry<K, T>, key: string) => {\r\n if (this.isExpired(entry)) {\r\n this.clearCacheByKey(key);\r\n }\r\n });\r\n this.gcLock = false;\r\n return true;\r\n }\r\n\r\n /**\r\n * Return true if cache entry is expired\r\n */\r\n isExpired<K, T>(entry: NgHttpCachingEntry<K, T>): 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 (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // config/default lifetime\r\n let lifetime: number = this.config.lifetime;\r\n // request has own lifetime\r\n const headerLifetime = entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);\r\n if (headerLifetime) {\r\n lifetime = +headerLifetime;\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 || isNaN(lifetime)) {\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<K, T>(entry: NgHttpCachingEntry<K, T>): 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 (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // different version\r\n if (this.config.version !== entry.version) {\r\n return false;\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<K>(req: HttpRequest<K>): 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 (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 * Default key is http method plus url with query parameters, eg.:\r\n * `GET@https://github.com/nigrosimone/ng-http-caching`\r\n */\r\n getKey<K>(req: HttpRequest<K>): 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 (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // default key is req.method plus url with query parameters\r\n return req.method + '@' + req.urlWithParams;\r\n }\r\n\r\n /**\r\n * Return observable from cache\r\n */\r\n getFromQueue<K, T>(req: HttpRequest<K>): Observable<HttpEvent<T>> | undefined {\r\n const key: string = this.getKey(req);\r\n const cached: Observable<HttpEvent<T>> | undefined = 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<K, T>(req: HttpRequest<K>, obs: Observable<HttpEvent<T>>): 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<K>(req: HttpRequest<K>): boolean {\r\n const key: string = this.getKey(req);\r\n return this.queue.delete(key);\r\n }\r\n\r\n /**\r\n * Recursively Object.freeze simple Javascript structures consisting of plain objects, arrays, and primitives.\r\n * Make the data immutable.\r\n * @returns immutable object\r\n */\r\n private deepFreeze<S>(object: S): Readonly<S> {\r\n // No freezing in production (for better performance).\r\n if (!this.devMode || !object || typeof object !== 'object') {\r\n return object as Readonly<S>;\r\n }\r\n\r\n // When already frozen, we assume its children are frozen (for better performance).\r\n // This should be true if you always use `deepFreeze` to freeze objects.\r\n //\r\n // Note that Object.isFrozen will also return `true` for primitives (numbers,\r\n // strings, booleans, undefined, null), so there is no need to check for\r\n // those explicitly.\r\n if (Object.isFrozen(object)) {\r\n return object as Readonly<S>;\r\n }\r\n\r\n // At this point we know that we're dealing with either an array or plain object, so\r\n // just freeze it and recurse on its values.\r\n Object.freeze(object);\r\n Object.keys(object).forEach(key => this.deepFreeze((object as any)[key]));\r\n\r\n return object as Readonly<S>;\r\n }\r\n}\r\n","import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { asapScheduler, Observable, scheduled } from 'rxjs';\r\nimport { tap, finalize, share } from 'rxjs/operators';\r\nimport { NgHttpCachingService, NgHttpCachingHeadersList } from './ng-http-caching.service';\r\n\r\n/**\r\n * Fix for https://github.com/ReactiveX/rxjs/issues/7241\r\n */\r\nfunction* _of<T>(value: T): Generator<T> {\r\n yield value;\r\n}\r\n\r\n@Injectable()\r\nexport class NgHttpCachingInterceptorService implements HttpInterceptor {\r\n\r\n constructor(private readonly cacheService: NgHttpCachingService) { }\r\n\r\n intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n // run garbage collector\r\n this.cacheService.runGc();\r\n\r\n // Don't cache if it's not cacheable\r\n if (!this.cacheService.isCacheable(req)) {\r\n return this.sendRequest(req, next);\r\n }\r\n\r\n // Checked if there is pending response for this request\r\n const cachedObservable: Observable<HttpEvent<any>> | undefined = this.cacheService.getFromQueue(req);\r\n if (cachedObservable) {\r\n // console.log('cachedObservable');\r\n return scheduled(cachedObservable, asapScheduler);\r\n }\r\n\r\n // Checked if there is cached response for this request\r\n const cachedResponse: HttpResponse<any> | undefined = this.cacheService.getFromCache(req);\r\n if (cachedResponse) {\r\n // console.log('cachedResponse');\r\n return scheduled(_of(cachedResponse.clone()), asapScheduler);\r\n }\r\n\r\n // If the request of going through for first time\r\n // then let the request proceed and cache the response\r\n // console.log('sendRequest', req);\r\n const shared = this.sendRequest(req, next).pipe(\r\n tap(event => {\r\n if (event instanceof HttpResponse) {\r\n this.cacheService.addToCache(req, event.clone());\r\n }\r\n }),\r\n finalize(() => {\r\n // delete pending request\r\n this.cacheService.deleteFromQueue(req);\r\n }),\r\n share()\r\n );\r\n\r\n // add pending request to queue for cache parallell request\r\n this.cacheService.addToQueue(req, shared);\r\n\r\n return shared;\r\n }\r\n\r\n /**\r\n * Send http request (next handler)\r\n */\r\n sendRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n let cloned: HttpRequest<any> = req.clone();\r\n // trim custom headers before send request\r\n NgHttpCachingHeadersList.forEach(ngHttpCachingHeaders => {\r\n if (cloned.headers.has(ngHttpCachingHeaders)) {\r\n cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });\r\n }\r\n });\r\n return next.handle(cloned);\r\n }\r\n}\r\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 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})\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","import { NgHttpCachingStorageInterface } from './ng-http-caching-storage.interface';\r\nimport { NgHttpCachingEntry } from '../ng-http-caching.service';\r\nimport { HttpHeaders, HttpParams, HttpRequest, HttpResponse } from '@angular/common/http';\r\n\r\nconst KEY_PREFIX = 'NgHttpCaching::';\r\n\r\nexport const serializeRequest = (req: HttpRequest<any>): string => {\r\n const request = req.clone(); // Make a clone, useful for doing destructive things\r\n return JSON.stringify({\r\n headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n request.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ),\r\n method: request.method, // The Request Method, e.g. GET, POST, DELETE\r\n url: request.url, // The URL\r\n params: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n request.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ), // The request parameters\r\n withCredentials: request.withCredentials, // Whether credentials are being sent\r\n respnseType: request.responseType, // The response type\r\n body: request.serializeBody() // Serialize the body, all well and good since we are working on a clone\r\n });\r\n}\r\n\r\nexport const serializeResponse = (res: HttpResponse<any>): string => {\r\n const response = res.clone();\r\n return JSON.stringify({\r\n headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n response.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, response.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ),\r\n status: response.status,\r\n statusText: response.statusText,\r\n url: response.url,\r\n body: response.body // Serialize the body, all well and good since we are working on a clone \r\n });\r\n}\r\n\r\nexport const deserializeRequest = <T = any>(req: string): HttpRequest<T> => {\r\n const request = JSON.parse(req);\r\n const headers = new HttpHeaders(request.headers);\r\n const params = new HttpParams(); // Probably some way to make this a one-liner, but alas, there are no good docs\r\n for (const parameter in request.params) {\r\n request.params[parameter].forEach((paramValue: string) => params.append(parameter, paramValue));\r\n }\r\n return new HttpRequest(request.method, request.url, request.body, {\r\n headers,\r\n params,\r\n responseType: request.responseType,\r\n withCredentials: request.withCredentials\r\n });\r\n}\r\n\r\nexport const deserializeResponse = <T = any>(res: string): HttpResponse<T> => {\r\n const response = JSON.parse(res);\r\n return new HttpResponse<T>({\r\n url: response.url,\r\n headers: new HttpHeaders(response.headers),\r\n body: response.body,\r\n status: response.status,\r\n statusText: response.statusText,\r\n });\r\n}\r\n\r\nexport class NgHttpCachingBrowserStorage implements NgHttpCachingStorageInterface {\r\n\r\n constructor(private storage: Storage) { }\r\n\r\n get size(): number {\r\n let count = 0;\r\n for (let i = 0, e = this.storage.length; i < e; i++) {\r\n const key = this.storage.key(i);\r\n if (key && key.startsWith(KEY_PREFIX)) {\r\n count++;\r\n }\r\n }\r\n return count;\r\n }\r\n\r\n clear(): void {\r\n for (let i = 0, e = this.storage.length; i < e; i++) {\r\n const key = this.storage.key(i);\r\n if (key && key.startsWith(KEY_PREFIX)) {\r\n this.storage.removeItem(key);\r\n }\r\n }\r\n }\r\n\r\n delete(key: string): boolean {\r\n this.storage.removeItem(KEY_PREFIX + key);\r\n return true;\r\n }\r\n\r\n forEach(callbackfn: (value: NgHttpCachingEntry, key: string) => void): void {\r\n // iterate this.storage\r\n const lenPrefix = KEY_PREFIX.length;\r\n for (let i = 0, e = this.storage.length; i < e; i++) {\r\n const key = this.storage.key(i);\r\n if (key && key.startsWith(KEY_PREFIX)) {\r\n const value = this.get(key.substring(lenPrefix));\r\n if (value) {\r\n callbackfn(value, key);\r\n }\r\n }\r\n }\r\n }\r\n\r\n get(key: string): Readonly<NgHttpCachingEntry> | undefined {\r\n const item = this.storage.getItem(KEY_PREFIX + key);\r\n if (item) {\r\n const parsedItem: StorageEntry = JSON.parse(item);\r\n return {\r\n url: parsedItem.url,\r\n response: deserializeResponse(parsedItem.response),\r\n request: deserializeRequest(parsedItem.request),\r\n addedTime: parsedItem.addedTime,\r\n version: parsedItem.version\r\n };\r\n }\r\n return undefined;\r\n }\r\n\r\n has(key: string): boolean {\r\n return this.storage.getItem(KEY_PREFIX + key) !== undefined;\r\n }\r\n\r\n set(key: string, value: NgHttpCachingEntry): void {\r\n this.storage.setItem(KEY_PREFIX + key, JSON.stringify({\r\n url: value.url,\r\n response: serializeResponse(value.response),\r\n request: serializeRequest(value.request),\r\n addedTime: value.addedTime\r\n } as StorageEntry));\r\n }\r\n}\r\n\r\ninterface StorageEntry {\r\n url: string;\r\n response: string;\r\n request: string;\r\n addedTime: number;\r\n version: string;\r\n}\r\n","import { NgHttpCachingBrowserStorage } from './ng-http-caching-browser-storage';\r\n\r\nexport class NgHttpCachingLocalStorage extends NgHttpCachingBrowserStorage {\r\n\r\n constructor() {\r\n super(localStorage);\r\n }\r\n}\r\n","import { NgHttpCachingBrowserStorage } from './ng-http-caching-browser-storage';\r\n\r\nexport class NgHttpCachingSessionStorage extends NgHttpCachingBrowserStorage {\r\n\r\n constructor() {\r\n super(sessionStorage);\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\nexport * from './lib/storage/ng-http-caching-local-storage';\r\nexport * from './lib/storage/ng-http-caching-session-storage';\r\nexport * from './lib/storage/ng-http-caching-browser-storage';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.NgHttpCachingService"],"mappings":"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"}
|