ng-http-caching 15.2.4 → 16.0.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.
Files changed (30) hide show
  1. package/README.md +1 -0
  2. package/esm2022/lib/ng-http-caching-interceptor.service.mjs +72 -0
  3. package/esm2022/lib/ng-http-caching.module.mjs +43 -0
  4. package/esm2022/lib/ng-http-caching.service.mjs +331 -0
  5. package/{esm2020 → esm2022}/lib/storage/ng-http-caching-browser-storage.mjs +122 -122
  6. package/{esm2020 → esm2022}/lib/storage/ng-http-caching-local-storage.mjs +6 -6
  7. package/{esm2020 → esm2022}/lib/storage/ng-http-caching-memory-storage.mjs +26 -26
  8. package/{esm2020 → esm2022}/lib/storage/ng-http-caching-session-storage.mjs +6 -6
  9. package/{esm2020 → esm2022}/lib/storage/ng-http-caching-storage.interface.mjs +1 -1
  10. package/{esm2020 → esm2022}/ng-http-caching.mjs +4 -4
  11. package/{esm2020 → esm2022}/public-api.mjs +11 -11
  12. package/{fesm2020 → fesm2022}/ng-http-caching.mjs +579 -578
  13. package/fesm2022/ng-http-caching.mjs.map +1 -0
  14. package/index.d.ts +5 -5
  15. package/lib/ng-http-caching-interceptor.service.d.ts +15 -15
  16. package/lib/ng-http-caching.module.d.ts +9 -9
  17. package/lib/ng-http-caching.service.d.ts +214 -213
  18. package/lib/storage/ng-http-caching-browser-storage.d.ts +18 -18
  19. package/lib/storage/ng-http-caching-local-storage.d.ts +4 -4
  20. package/lib/storage/ng-http-caching-memory-storage.d.ts +12 -12
  21. package/lib/storage/ng-http-caching-session-storage.d.ts +4 -4
  22. package/lib/storage/ng-http-caching-storage.interface.d.ts +31 -31
  23. package/package.json +7 -13
  24. package/public-api.d.ts +8 -8
  25. package/esm2020/lib/ng-http-caching-interceptor.service.mjs +0 -71
  26. package/esm2020/lib/ng-http-caching.module.mjs +0 -42
  27. package/esm2020/lib/ng-http-caching.service.mjs +0 -329
  28. package/fesm2015/ng-http-caching.mjs +0 -606
  29. package/fesm2015/ng-http-caching.mjs.map +0 -1
  30. package/fesm2020/ng-http-caching.mjs.map +0 -1
@@ -4,600 +4,601 @@ import { InjectionToken, VERSION, isDevMode, Injectable, Inject, Optional, NgMod
4
4
  import { scheduled, asapScheduler } from 'rxjs';
5
5
  import { tap, finalize, shareReplay } from 'rxjs/operators';
6
6
 
7
- class NgHttpCachingMemoryStorage {
8
- constructor() {
9
- this.store = new Map();
10
- }
11
- get size() {
12
- return this.store.size;
13
- }
14
- clear() {
15
- this.store.clear();
16
- }
17
- delete(key) {
18
- return this.store.delete(key);
19
- }
20
- forEach(callbackfn) {
21
- return this.store.forEach(callbackfn);
22
- }
23
- get(key) {
24
- return this.store.get(key);
25
- }
26
- has(key) {
27
- return this.store.has(key);
28
- }
29
- set(key, value) {
30
- this.store.set(key, value);
31
- }
7
+ class NgHttpCachingMemoryStorage {
8
+ constructor() {
9
+ this.store = new Map();
10
+ }
11
+ get size() {
12
+ return this.store.size;
13
+ }
14
+ clear() {
15
+ this.store.clear();
16
+ }
17
+ delete(key) {
18
+ return this.store.delete(key);
19
+ }
20
+ forEach(callbackfn) {
21
+ return this.store.forEach(callbackfn);
22
+ }
23
+ get(key) {
24
+ return this.store.get(key);
25
+ }
26
+ has(key) {
27
+ return this.store.has(key);
28
+ }
29
+ set(key, value) {
30
+ this.store.set(key, value);
31
+ }
32
32
  }
33
33
 
34
- const NG_HTTP_CACHING_CONFIG = new InjectionToken('ng-http-caching.config');
35
- var NgHttpCachingStrategy;
36
- (function (NgHttpCachingStrategy) {
37
- /**
38
- * All request are cacheable if HTTP method is into `allowedMethod`
39
- */
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
- */
44
- NgHttpCachingStrategy["DISALLOW_ALL"] = "DISALLOW_ALL";
45
- })(NgHttpCachingStrategy || (NgHttpCachingStrategy = {}));
46
- var NgHttpCachingHeaders;
47
- (function (NgHttpCachingHeaders) {
48
- /**
49
- * Request is cacheable if HTTP method is into `allowedMethod`
50
- */
51
- NgHttpCachingHeaders["ALLOW_CACHE"] = "X-NG-HTTP-CACHING-ALLOW-CACHE";
52
- /**
53
- * Request isn't cacheable
54
- */
55
- NgHttpCachingHeaders["DISALLOW_CACHE"] = "X-NG-HTTP-CACHING-DISALLOW-CACHE";
56
- /**
57
- * Specific cache lifetime for the request
58
- */
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
- */
64
- NgHttpCachingHeaders["TAG"] = "X-NG-HTTP-CACHING-TAG";
65
- })(NgHttpCachingHeaders || (NgHttpCachingHeaders = {}));
66
- const NgHttpCachingHeadersList = Object.values(NgHttpCachingHeaders);
67
- const NG_HTTP_CACHING_SECOND_IN_MS = 1000;
68
- const NG_HTTP_CACHING_MINUTE_IN_MS = NG_HTTP_CACHING_SECOND_IN_MS * 60;
69
- const NG_HTTP_CACHING_HOUR_IN_MS = NG_HTTP_CACHING_MINUTE_IN_MS * 60;
70
- const NG_HTTP_CACHING_DAY_IN_MS = NG_HTTP_CACHING_HOUR_IN_MS * 24;
71
- const NG_HTTP_CACHING_WEEK_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 7;
72
- const NG_HTTP_CACHING_MONTH_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 30;
73
- const NG_HTTP_CACHING_YEAR_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 365;
74
- const NgHttpCachingConfigDefault = {
75
- store: new NgHttpCachingMemoryStorage(),
76
- lifetime: NG_HTTP_CACHING_HOUR_IN_MS,
77
- version: VERSION.major,
78
- allowedMethod: ['GET', 'HEAD'],
79
- cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,
80
- };
81
- class NgHttpCachingService {
82
- constructor(config) {
83
- this.queue = new Map();
84
- this.gcLock = false;
85
- this.devMode = isDevMode();
86
- if (config) {
87
- this.config = { ...NgHttpCachingConfigDefault, ...config };
88
- }
89
- else {
90
- this.config = { ...NgHttpCachingConfigDefault };
91
- }
92
- // start cache clean
93
- this.runGc();
94
- }
95
- /**
96
- * Return the config
97
- */
98
- getConfig() {
99
- return this.config;
100
- }
101
- /**
102
- * Return the queue map
103
- */
104
- getQueue() {
105
- return this.queue;
106
- }
107
- /**
108
- * Return the cache store
109
- */
110
- getStore() {
111
- return this.config.store;
112
- }
113
- /**
114
- * Return response from cache
115
- */
116
- getFromCache(req) {
117
- const key = this.getKey(req);
118
- const cached = this.config.store.get(key);
119
- if (!cached) {
120
- return undefined;
121
- }
122
- if (this.isExpired(cached)) {
123
- this.clearCacheByKey(key);
124
- return undefined;
125
- }
126
- return this.deepFreeze(cached.response);
127
- }
128
- /**
129
- * Add response to cache
130
- */
131
- addToCache(req, res) {
132
- const entry = {
133
- url: req.urlWithParams,
134
- response: res,
135
- request: req,
136
- addedTime: Date.now(),
137
- version: this.config.version,
138
- };
139
- if (this.isValid(entry)) {
140
- const key = this.getKey(req);
141
- this.config.store.set(key, entry);
142
- return true;
143
- }
144
- return false;
145
- }
146
- /**
147
- * Delete response from cache
148
- */
149
- deleteFromCache(req) {
150
- const key = this.getKey(req);
151
- return this.clearCacheByKey(key);
152
- }
153
- /**
154
- * Clear the cache
155
- */
156
- clearCache() {
157
- this.config.store.clear();
158
- }
159
- /**
160
- * Clear the cache by key
161
- */
162
- clearCacheByKey(key) {
163
- return this.config.store.delete(key);
164
- }
165
- /**
166
- * Clear the cache by regex
167
- */
168
- clearCacheByRegex(regex) {
169
- this.config.store.forEach((_, key) => {
170
- if (regex.test(key)) {
171
- this.clearCacheByKey(key);
172
- }
173
- });
174
- }
175
- /**
176
- * Clear the cache by TAG
177
- */
178
- clearCacheByTag(tag) {
179
- this.config.store.forEach((entry, key) => {
180
- const tagHeader = entry.request.headers.get(NgHttpCachingHeaders.TAG);
181
- if (tagHeader && tagHeader.split(',').includes(tag)) {
182
- this.clearCacheByKey(key);
183
- }
184
- });
185
- }
186
- /**
187
- * Run garbage collector (delete expired cache entry)
188
- */
189
- runGc() {
190
- if (this.gcLock) {
191
- return false;
192
- }
193
- this.gcLock = true;
194
- this.config.store.forEach((entry, key) => {
195
- if (this.isExpired(entry)) {
196
- this.clearCacheByKey(key);
197
- }
198
- });
199
- this.gcLock = false;
200
- return true;
201
- }
202
- /**
203
- * Return true if cache entry is expired
204
- */
205
- isExpired(entry) {
206
- // if user provide custom method, use it
207
- if (typeof this.config.isExpired === 'function') {
208
- const result = this.config.isExpired(entry);
209
- // if result is undefined, normal behaviour is provided
210
- if (result !== undefined) {
211
- return result;
212
- }
213
- }
214
- // config/default lifetime
215
- let lifetime = this.config.lifetime;
216
- // request has own lifetime
217
- const headerLifetime = entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);
218
- if (headerLifetime) {
219
- lifetime = +headerLifetime;
220
- }
221
- // never expire if 0
222
- if (lifetime === 0) {
223
- return false;
224
- }
225
- // wrong lifetime
226
- if (lifetime < 0 || isNaN(lifetime)) {
227
- throw new Error('lifetime must be greater than or equal 0');
228
- }
229
- return entry.addedTime + lifetime < Date.now();
230
- }
231
- /**
232
- * Return true if cache entry is valid for store in the cache
233
- */
234
- isValid(entry) {
235
- // if user provide custom method, use it
236
- if (typeof this.config.isValid === 'function') {
237
- const result = this.config.isValid(entry);
238
- // if result is undefined, normal behaviour is provided
239
- if (result !== undefined) {
240
- return result;
241
- }
242
- }
243
- // different version
244
- if (this.config.version !== entry.version) {
245
- return false;
246
- }
247
- return true;
248
- }
249
- /**
250
- * Return true if the request is cacheable
251
- */
252
- isCacheable(req) {
253
- // if user provide custom method, use it
254
- if (typeof this.config.isCacheable === 'function') {
255
- const result = this.config.isCacheable(req);
256
- // if result is undefined, normal behaviour is provided
257
- if (result !== undefined) {
258
- return result;
259
- }
260
- }
261
- // request has disallow cache header
262
- if (req.headers.has(NgHttpCachingHeaders.DISALLOW_CACHE)) {
263
- return false;
264
- }
265
- // strategy is disallow all...
266
- if (this.config.cacheStrategy === NgHttpCachingStrategy.DISALLOW_ALL) {
267
- // request isn't allowed if come without allow header
268
- if (!req.headers.has(NgHttpCachingHeaders.ALLOW_CACHE)) {
269
- return false;
270
- }
271
- }
272
- // if allowed method is only ALL, allow all http methos
273
- if (this.config.allowedMethod.length === 1) {
274
- if (this.config.allowedMethod[0] === 'ALL') {
275
- return true;
276
- }
277
- }
278
- // request is allowed if method is in allowedMethod
279
- return this.config.allowedMethod.indexOf(req.method) !== -1;
280
- }
281
- /**
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`
285
- */
286
- getKey(req) {
287
- // if user provide custom method, use it
288
- if (typeof this.config.getKey === 'function') {
289
- const result = this.config.getKey(req);
290
- // if result is undefined, normal behaviour is provided
291
- if (result !== undefined) {
292
- return result;
293
- }
294
- }
295
- // default key is req.method plus url with query parameters
296
- return req.method + '@' + req.urlWithParams;
297
- }
298
- /**
299
- * Return observable from cache
300
- */
301
- getFromQueue(req) {
302
- const key = this.getKey(req);
303
- const cached = this.queue.get(key);
304
- if (!cached) {
305
- return undefined;
306
- }
307
- return cached;
308
- }
309
- /**
310
- * Add observable to cache
311
- */
312
- addToQueue(req, obs) {
313
- const key = this.getKey(req);
314
- this.queue.set(key, obs);
315
- }
316
- /**
317
- * Delete observable from cache
318
- */
319
- deleteFromQueue(req) {
320
- const key = this.getKey(req);
321
- return this.queue.delete(key);
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
- }
348
- }
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: [{
352
- type: Injectable
353
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
354
- type: Inject,
355
- args: [NG_HTTP_CACHING_CONFIG]
356
- }, {
357
- type: Optional
34
+ const NG_HTTP_CACHING_CONFIG = new InjectionToken('ng-http-caching.config');
35
+ var NgHttpCachingStrategy;
36
+ (function (NgHttpCachingStrategy) {
37
+ /**
38
+ * All request are cacheable if HTTP method is into `allowedMethod`
39
+ */
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
+ */
44
+ NgHttpCachingStrategy["DISALLOW_ALL"] = "DISALLOW_ALL";
45
+ })(NgHttpCachingStrategy || (NgHttpCachingStrategy = {}));
46
+ var NgHttpCachingHeaders;
47
+ (function (NgHttpCachingHeaders) {
48
+ /**
49
+ * Request is cacheable if HTTP method is into `allowedMethod`
50
+ */
51
+ NgHttpCachingHeaders["ALLOW_CACHE"] = "X-NG-HTTP-CACHING-ALLOW-CACHE";
52
+ /**
53
+ * Request isn't cacheable
54
+ */
55
+ NgHttpCachingHeaders["DISALLOW_CACHE"] = "X-NG-HTTP-CACHING-DISALLOW-CACHE";
56
+ /**
57
+ * Specific cache lifetime for the request
58
+ */
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
+ */
64
+ NgHttpCachingHeaders["TAG"] = "X-NG-HTTP-CACHING-TAG";
65
+ })(NgHttpCachingHeaders || (NgHttpCachingHeaders = {}));
66
+ const NgHttpCachingHeadersList = Object.values(NgHttpCachingHeaders);
67
+ const NG_HTTP_CACHING_SECOND_IN_MS = 1000;
68
+ const NG_HTTP_CACHING_MINUTE_IN_MS = NG_HTTP_CACHING_SECOND_IN_MS * 60;
69
+ const NG_HTTP_CACHING_HOUR_IN_MS = NG_HTTP_CACHING_MINUTE_IN_MS * 60;
70
+ const NG_HTTP_CACHING_DAY_IN_MS = NG_HTTP_CACHING_HOUR_IN_MS * 24;
71
+ const NG_HTTP_CACHING_WEEK_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 7;
72
+ const NG_HTTP_CACHING_MONTH_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 30;
73
+ const NG_HTTP_CACHING_YEAR_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 365;
74
+ const NgHttpCachingConfigDefault = {
75
+ store: new NgHttpCachingMemoryStorage(),
76
+ lifetime: NG_HTTP_CACHING_HOUR_IN_MS,
77
+ version: VERSION.major,
78
+ allowedMethod: ['GET', 'HEAD'],
79
+ cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,
80
+ };
81
+ class NgHttpCachingService {
82
+ constructor(config) {
83
+ this.queue = new Map();
84
+ this.gcLock = false;
85
+ this.devMode = isDevMode();
86
+ if (config) {
87
+ this.config = { ...NgHttpCachingConfigDefault, ...config };
88
+ }
89
+ else {
90
+ this.config = { ...NgHttpCachingConfigDefault };
91
+ }
92
+ // start cache clean
93
+ this.runGc();
94
+ }
95
+ /**
96
+ * Return the config
97
+ */
98
+ getConfig() {
99
+ return this.config;
100
+ }
101
+ /**
102
+ * Return the queue map
103
+ */
104
+ getQueue() {
105
+ return this.queue;
106
+ }
107
+ /**
108
+ * Return the cache store
109
+ */
110
+ getStore() {
111
+ return this.config.store;
112
+ }
113
+ /**
114
+ * Return response from cache
115
+ */
116
+ getFromCache(req) {
117
+ const key = this.getKey(req);
118
+ const cached = this.config.store.get(key);
119
+ if (!cached) {
120
+ return undefined;
121
+ }
122
+ if (this.isExpired(cached)) {
123
+ this.clearCacheByKey(key);
124
+ return undefined;
125
+ }
126
+ return this.deepFreeze(cached.response);
127
+ }
128
+ /**
129
+ * Add response to cache
130
+ */
131
+ addToCache(req, res) {
132
+ const entry = {
133
+ url: req.urlWithParams,
134
+ response: res,
135
+ request: req,
136
+ addedTime: Date.now(),
137
+ version: this.config.version,
138
+ };
139
+ if (this.isValid(entry)) {
140
+ const key = this.getKey(req);
141
+ this.config.store.set(key, entry);
142
+ return true;
143
+ }
144
+ return false;
145
+ }
146
+ /**
147
+ * Delete response from cache
148
+ */
149
+ deleteFromCache(req) {
150
+ const key = this.getKey(req);
151
+ return this.clearCacheByKey(key);
152
+ }
153
+ /**
154
+ * Clear the cache
155
+ */
156
+ clearCache() {
157
+ this.config.store.clear();
158
+ }
159
+ /**
160
+ * Clear the cache by key
161
+ */
162
+ clearCacheByKey(key) {
163
+ return this.config.store.delete(key);
164
+ }
165
+ /**
166
+ * Clear the cache by regex
167
+ */
168
+ clearCacheByRegex(regex) {
169
+ this.config.store.forEach((_, key) => {
170
+ if (regex.test(key)) {
171
+ this.clearCacheByKey(key);
172
+ }
173
+ });
174
+ }
175
+ /**
176
+ * Clear the cache by TAG
177
+ */
178
+ clearCacheByTag(tag) {
179
+ this.config.store.forEach((entry, key) => {
180
+ const tagHeader = entry.request.headers.get(NgHttpCachingHeaders.TAG);
181
+ if (tagHeader && tagHeader.split(',').includes(tag)) {
182
+ this.clearCacheByKey(key);
183
+ }
184
+ });
185
+ }
186
+ /**
187
+ * Run garbage collector (delete expired cache entry)
188
+ */
189
+ runGc() {
190
+ if (this.gcLock) {
191
+ return false;
192
+ }
193
+ this.gcLock = true;
194
+ this.config.store.forEach((entry, key) => {
195
+ if (this.isExpired(entry)) {
196
+ this.clearCacheByKey(key);
197
+ }
198
+ });
199
+ this.gcLock = false;
200
+ return true;
201
+ }
202
+ /**
203
+ * Return true if cache entry is expired
204
+ */
205
+ isExpired(entry) {
206
+ // if user provide custom method, use it
207
+ if (typeof this.config.isExpired === 'function') {
208
+ const result = this.config.isExpired(entry);
209
+ // if result is undefined, normal behaviour is provided
210
+ if (result !== undefined) {
211
+ return result;
212
+ }
213
+ }
214
+ // config/default lifetime
215
+ let lifetime = this.config.lifetime;
216
+ // request has own lifetime
217
+ const headerLifetime = entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);
218
+ if (headerLifetime) {
219
+ lifetime = +headerLifetime;
220
+ }
221
+ // never expire if 0
222
+ if (lifetime === 0) {
223
+ return false;
224
+ }
225
+ // wrong lifetime
226
+ if (lifetime < 0 || isNaN(lifetime)) {
227
+ throw new Error('lifetime must be greater than or equal 0');
228
+ }
229
+ return entry.addedTime + lifetime < Date.now();
230
+ }
231
+ /**
232
+ * Return true if cache entry is valid for store in the cache
233
+ * Default behaviour is whether the status code falls in the 2xx range.
234
+ */
235
+ isValid(entry) {
236
+ // if user provide custom method, use it
237
+ if (typeof this.config.isValid === 'function') {
238
+ const result = this.config.isValid(entry);
239
+ // if result is undefined, normal behaviour is provided
240
+ if (result !== undefined) {
241
+ return result;
242
+ }
243
+ }
244
+ // different version
245
+ if (this.config.version !== entry.version) {
246
+ return false;
247
+ }
248
+ return entry.response.ok;
249
+ }
250
+ /**
251
+ * Return true if the request is cacheable
252
+ */
253
+ isCacheable(req) {
254
+ // if user provide custom method, use it
255
+ if (typeof this.config.isCacheable === 'function') {
256
+ const result = this.config.isCacheable(req);
257
+ // if result is undefined, normal behaviour is provided
258
+ if (result !== undefined) {
259
+ return result;
260
+ }
261
+ }
262
+ // request has disallow cache header
263
+ if (req.headers.has(NgHttpCachingHeaders.DISALLOW_CACHE)) {
264
+ return false;
265
+ }
266
+ // strategy is disallow all...
267
+ if (this.config.cacheStrategy === NgHttpCachingStrategy.DISALLOW_ALL) {
268
+ // request isn't allowed if come without allow header
269
+ if (!req.headers.has(NgHttpCachingHeaders.ALLOW_CACHE)) {
270
+ return false;
271
+ }
272
+ }
273
+ // if allowed method is only ALL, allow all http methos
274
+ if (this.config.allowedMethod.length === 1) {
275
+ if (this.config.allowedMethod[0] === 'ALL') {
276
+ return true;
277
+ }
278
+ }
279
+ // request is allowed if method is in allowedMethod
280
+ return this.config.allowedMethod.indexOf(req.method) !== -1;
281
+ }
282
+ /**
283
+ * Return the cache key.
284
+ * Default key is http method plus url with query parameters, eg.:
285
+ * `GET@https://github.com/nigrosimone/ng-http-caching`
286
+ */
287
+ getKey(req) {
288
+ // if user provide custom method, use it
289
+ if (typeof this.config.getKey === 'function') {
290
+ const result = this.config.getKey(req);
291
+ // if result is undefined, normal behaviour is provided
292
+ if (result !== undefined) {
293
+ return result;
294
+ }
295
+ }
296
+ // default key is req.method plus url with query parameters
297
+ return req.method + '@' + req.urlWithParams;
298
+ }
299
+ /**
300
+ * Return observable from cache
301
+ */
302
+ getFromQueue(req) {
303
+ const key = this.getKey(req);
304
+ const cached = this.queue.get(key);
305
+ if (!cached) {
306
+ return undefined;
307
+ }
308
+ return cached;
309
+ }
310
+ /**
311
+ * Add observable to cache
312
+ */
313
+ addToQueue(req, obs) {
314
+ const key = this.getKey(req);
315
+ this.queue.set(key, obs);
316
+ }
317
+ /**
318
+ * Delete observable from cache
319
+ */
320
+ deleteFromQueue(req) {
321
+ const key = this.getKey(req);
322
+ return this.queue.delete(key);
323
+ }
324
+ /**
325
+ * Recursively Object.freeze simple Javascript structures consisting of plain objects, arrays, and primitives.
326
+ * Make the data immutable.
327
+ * @returns immutable object
328
+ */
329
+ deepFreeze(object) {
330
+ // No freezing in production (for better performance).
331
+ if (!this.devMode || !object || typeof object !== 'object') {
332
+ return object;
333
+ }
334
+ // When already frozen, we assume its children are frozen (for better performance).
335
+ // This should be true if you always use `deepFreeze` to freeze objects.
336
+ //
337
+ // Note that Object.isFrozen will also return `true` for primitives (numbers,
338
+ // strings, booleans, undefined, null), so there is no need to check for
339
+ // those explicitly.
340
+ if (Object.isFrozen(object)) {
341
+ return object;
342
+ }
343
+ // At this point we know that we're dealing with either an array or plain object, so
344
+ // just freeze it and recurse on its values.
345
+ Object.freeze(object);
346
+ Object.keys(object).forEach(key => this.deepFreeze(object[key]));
347
+ return object;
348
+ }
349
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgHttpCachingService, deps: [{ token: NG_HTTP_CACHING_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
350
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgHttpCachingService }); }
351
+ }
352
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgHttpCachingService, decorators: [{
353
+ type: Injectable
354
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
355
+ type: Inject,
356
+ args: [NG_HTTP_CACHING_CONFIG]
357
+ }, {
358
+ type: Optional
358
359
  }] }]; } });
359
360
 
360
- /**
361
- * Fix for https://github.com/ReactiveX/rxjs/issues/7241
362
- */
363
- function* _of(value) {
364
- yield value;
365
- }
366
- class NgHttpCachingInterceptorService {
367
- constructor(cacheService) {
368
- this.cacheService = cacheService;
369
- }
370
- intercept(req, next) {
371
- // run garbage collector
372
- this.cacheService.runGc();
373
- // Don't cache if it's not cacheable
374
- if (!this.cacheService.isCacheable(req)) {
375
- return this.sendRequest(req, next);
376
- }
377
- // Checked if there is pending response for this request
378
- const cachedObservable = this.cacheService.getFromQueue(req);
379
- if (cachedObservable) {
380
- // console.log('cachedObservable',cachedObservable);
381
- return cachedObservable;
382
- }
383
- // Checked if there is cached response for this request
384
- const cachedResponse = this.cacheService.getFromCache(req);
385
- if (cachedResponse) {
386
- // console.log('cachedResponse');
387
- return scheduled(_of(cachedResponse.clone()), asapScheduler);
388
- }
389
- // If the request of going through for first time
390
- // then let the request proceed and cache the response
391
- // console.log('sendRequest', req);
392
- const shared = this.sendRequest(req, next).pipe(tap(event => {
393
- if (event instanceof HttpResponse) {
394
- this.cacheService.addToCache(req, event.clone());
395
- }
396
- }), finalize(() => {
397
- // delete pending request
398
- this.cacheService.deleteFromQueue(req);
399
- }), shareReplay());
400
- // add pending request to queue for cache parallell request
401
- this.cacheService.addToQueue(req, shared);
402
- return shared;
403
- }
404
- /**
405
- * Send http request (next handler)
406
- */
407
- sendRequest(req, next) {
408
- let cloned = req.clone();
409
- // trim custom headers before send request
410
- NgHttpCachingHeadersList.forEach(ngHttpCachingHeaders => {
411
- if (cloned.headers.has(ngHttpCachingHeaders)) {
412
- cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });
413
- }
414
- });
415
- return next.handle(cloned);
416
- }
417
- }
418
- NgHttpCachingInterceptorServicefac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingInterceptorService, deps: [{ token: NgHttpCachingService }], target: i0.ɵɵFactoryTarget.Injectable });
419
- NgHttpCachingInterceptorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingInterceptorService });
420
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingInterceptorService, decorators: [{
421
- type: Injectable
361
+ /**
362
+ * Fix for https://github.com/ReactiveX/rxjs/issues/7241
363
+ */
364
+ function* _of(value) {
365
+ yield value;
366
+ }
367
+ class NgHttpCachingInterceptorService {
368
+ constructor(cacheService) {
369
+ this.cacheService = cacheService;
370
+ }
371
+ intercept(req, next) {
372
+ // run garbage collector
373
+ this.cacheService.runGc();
374
+ // Don't cache if it's not cacheable
375
+ if (!this.cacheService.isCacheable(req)) {
376
+ return this.sendRequest(req, next);
377
+ }
378
+ // Checked if there is pending response for this request
379
+ const cachedObservable = this.cacheService.getFromQueue(req);
380
+ if (cachedObservable) {
381
+ // console.log('cachedObservable',cachedObservable);
382
+ return cachedObservable;
383
+ }
384
+ // Checked if there is cached response for this request
385
+ const cachedResponse = this.cacheService.getFromCache(req);
386
+ if (cachedResponse) {
387
+ // console.log('cachedResponse');
388
+ return scheduled(_of(cachedResponse.clone()), asapScheduler);
389
+ }
390
+ // If the request of going through for first time
391
+ // then let the request proceed and cache the response
392
+ // console.log('sendRequest', req);
393
+ const shared = this.sendRequest(req, next).pipe(tap(event => {
394
+ if (event instanceof HttpResponse) {
395
+ this.cacheService.addToCache(req, event.clone());
396
+ }
397
+ }), finalize(() => {
398
+ // delete pending request
399
+ this.cacheService.deleteFromQueue(req);
400
+ }), shareReplay());
401
+ // add pending request to queue for cache parallell request
402
+ this.cacheService.addToQueue(req, shared);
403
+ return shared;
404
+ }
405
+ /**
406
+ * Send http request (next handler)
407
+ */
408
+ sendRequest(req, next) {
409
+ let cloned = req.clone();
410
+ // trim custom headers before send request
411
+ NgHttpCachingHeadersList.forEach(ngHttpCachingHeaders => {
412
+ if (cloned.headers.has(ngHttpCachingHeaders)) {
413
+ cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });
414
+ }
415
+ });
416
+ return next.handle(cloned);
417
+ }
418
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgHttpCachingInterceptorService, deps: [{ token: NgHttpCachingService }], target: i0.ɵɵFactoryTarget.Injectable }); }
419
+ static { thisprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgHttpCachingInterceptorService }); }
420
+ }
421
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgHttpCachingInterceptorService, decorators: [{
422
+ type: Injectable
422
423
  }], ctorParameters: function () { return [{ type: NgHttpCachingService }]; } });
423
424
 
424
- class NgHttpCachingModule {
425
- static forRoot(ngHttpCachingConfig) {
426
- return {
427
- ngModule: NgHttpCachingModule,
428
- providers: [
429
- {
430
- provide: NG_HTTP_CACHING_CONFIG,
431
- useValue: ngHttpCachingConfig,
432
- },
433
- ],
434
- };
435
- }
436
- }
437
- NgHttpCachingModulefac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
438
- NgHttpCachingModulemod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingModule });
439
- NgHttpCachingModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingModule, providers: [
440
- NgHttpCachingService,
441
- {
442
- provide: HTTP_INTERCEPTORS,
443
- useClass: NgHttpCachingInterceptorService,
444
- multi: true,
445
- },
446
- ] });
447
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: NgHttpCachingModule, decorators: [{
448
- type: NgModule,
449
- args: [{
450
- providers: [
451
- NgHttpCachingService,
452
- {
453
- provide: HTTP_INTERCEPTORS,
454
- useClass: NgHttpCachingInterceptorService,
455
- multi: true,
456
- },
457
- ]
458
- }]
425
+ class NgHttpCachingModule {
426
+ static forRoot(ngHttpCachingConfig) {
427
+ return {
428
+ ngModule: NgHttpCachingModule,
429
+ providers: [
430
+ {
431
+ provide: NG_HTTP_CACHING_CONFIG,
432
+ useValue: ngHttpCachingConfig,
433
+ },
434
+ ],
435
+ };
436
+ }
437
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgHttpCachingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
438
+ static { thismod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.0.0", ngImport: i0, type: NgHttpCachingModule }); }
439
+ static { thisinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgHttpCachingModule, providers: [
440
+ NgHttpCachingService,
441
+ {
442
+ provide: HTTP_INTERCEPTORS,
443
+ useClass: NgHttpCachingInterceptorService,
444
+ multi: true,
445
+ },
446
+ ] }); }
447
+ }
448
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgHttpCachingModule, decorators: [{
449
+ type: NgModule,
450
+ args: [{
451
+ providers: [
452
+ NgHttpCachingService,
453
+ {
454
+ provide: HTTP_INTERCEPTORS,
455
+ useClass: NgHttpCachingInterceptorService,
456
+ multi: true,
457
+ },
458
+ ]
459
+ }]
459
460
  }] });
460
461
 
461
- const KEY_PREFIX = 'NgHttpCaching::';
462
- const serializeRequest = (req) => {
463
- const request = req.clone(); // Make a clone, useful for doing destructive things
464
- return JSON.stringify({
465
- headers: Object.fromEntries(// Just a helper to make this into an object, not really required but makes the output nicer
466
- request.headers.keys().map(// Get all of the headers
467
- (key) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers
468
- )),
469
- method: request.method,
470
- url: request.url,
471
- params: Object.fromEntries(// Just a helper to make this into an object, not really required but makes the output nicer
472
- request.headers.keys().map(// Get all of the headers
473
- (key) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers
474
- )),
475
- withCredentials: request.withCredentials,
476
- respnseType: request.responseType,
477
- body: request.serializeBody() // Serialize the body, all well and good since we are working on a clone
478
- });
479
- };
480
- const serializeResponse = (res) => {
481
- const response = res.clone();
482
- return JSON.stringify({
483
- headers: Object.fromEntries(// Just a helper to make this into an object, not really required but makes the output nicer
484
- response.headers.keys().map(// Get all of the headers
485
- (key) => [key, response.headers.getAll(key)] // Get all of the corresponding values for the headers
486
- )),
487
- status: response.status,
488
- statusText: response.statusText,
489
- url: response.url,
490
- body: response.body // Serialize the body, all well and good since we are working on a clone
491
- });
492
- };
493
- const deserializeRequest = (req) => {
494
- const request = JSON.parse(req);
495
- const headers = new HttpHeaders(request.headers);
496
- const params = new HttpParams(); // Probably some way to make this a one-liner, but alas, there are no good docs
497
- for (const parameter in request.params) {
498
- request.params[parameter].forEach((paramValue) => params.append(parameter, paramValue));
499
- }
500
- return new HttpRequest(request.method, request.url, request.body, {
501
- headers,
502
- params,
503
- responseType: request.responseType,
504
- withCredentials: request.withCredentials
505
- });
506
- };
507
- const deserializeResponse = (res) => {
508
- const response = JSON.parse(res);
509
- return new HttpResponse({
510
- url: response.url,
511
- headers: new HttpHeaders(response.headers),
512
- body: response.body,
513
- status: response.status,
514
- statusText: response.statusText,
515
- });
516
- };
517
- class NgHttpCachingBrowserStorage {
518
- constructor(storage) {
519
- this.storage = storage;
520
- }
521
- get size() {
522
- let count = 0;
523
- for (let i = 0, e = this.storage.length; i < e; i++) {
524
- const key = this.storage.key(i);
525
- if (key && key.startsWith(KEY_PREFIX)) {
526
- count++;
527
- }
528
- }
529
- return count;
530
- }
531
- clear() {
532
- for (let i = 0, e = this.storage.length; i < e; i++) {
533
- const key = this.storage.key(i);
534
- if (key && key.startsWith(KEY_PREFIX)) {
535
- this.storage.removeItem(key);
536
- }
537
- }
538
- }
539
- delete(key) {
540
- this.storage.removeItem(KEY_PREFIX + key);
541
- return true;
542
- }
543
- forEach(callbackfn) {
544
- // iterate this.storage
545
- const lenPrefix = KEY_PREFIX.length;
546
- for (let i = 0, e = this.storage.length; i < e; i++) {
547
- const key = this.storage.key(i);
548
- if (key && key.startsWith(KEY_PREFIX)) {
549
- const value = this.get(key.substring(lenPrefix));
550
- if (value) {
551
- callbackfn(value, key);
552
- }
553
- }
554
- }
555
- }
556
- get(key) {
557
- const item = this.storage.getItem(KEY_PREFIX + key);
558
- if (item) {
559
- const parsedItem = JSON.parse(item);
560
- return {
561
- url: parsedItem.url,
562
- response: deserializeResponse(parsedItem.response),
563
- request: deserializeRequest(parsedItem.request),
564
- addedTime: parsedItem.addedTime,
565
- version: parsedItem.version
566
- };
567
- }
568
- return undefined;
569
- }
570
- has(key) {
571
- return this.storage.getItem(KEY_PREFIX + key) !== undefined;
572
- }
573
- set(key, value) {
574
- this.storage.setItem(KEY_PREFIX + key, JSON.stringify({
575
- url: value.url,
576
- response: serializeResponse(value.response),
577
- request: serializeRequest(value.request),
578
- addedTime: value.addedTime
579
- }));
580
- }
462
+ const KEY_PREFIX = 'NgHttpCaching::';
463
+ const serializeRequest = (req) => {
464
+ const request = req.clone(); // Make a clone, useful for doing destructive things
465
+ return JSON.stringify({
466
+ headers: Object.fromEntries(// Just a helper to make this into an object, not really required but makes the output nicer
467
+ request.headers.keys().map(// Get all of the headers
468
+ (key) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers
469
+ )),
470
+ method: request.method,
471
+ url: request.url,
472
+ params: Object.fromEntries(// Just a helper to make this into an object, not really required but makes the output nicer
473
+ request.headers.keys().map(// Get all of the headers
474
+ (key) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers
475
+ )),
476
+ withCredentials: request.withCredentials,
477
+ respnseType: request.responseType,
478
+ body: request.serializeBody() // Serialize the body, all well and good since we are working on a clone
479
+ });
480
+ };
481
+ const serializeResponse = (res) => {
482
+ const response = res.clone();
483
+ return JSON.stringify({
484
+ headers: Object.fromEntries(// Just a helper to make this into an object, not really required but makes the output nicer
485
+ response.headers.keys().map(// Get all of the headers
486
+ (key) => [key, response.headers.getAll(key)] // Get all of the corresponding values for the headers
487
+ )),
488
+ status: response.status,
489
+ statusText: response.statusText,
490
+ url: response.url,
491
+ body: response.body // Serialize the body, all well and good since we are working on a clone
492
+ });
493
+ };
494
+ const deserializeRequest = (req) => {
495
+ const request = JSON.parse(req);
496
+ const headers = new HttpHeaders(request.headers);
497
+ const params = new HttpParams(); // Probably some way to make this a one-liner, but alas, there are no good docs
498
+ for (const parameter in request.params) {
499
+ request.params[parameter].forEach((paramValue) => params.append(parameter, paramValue));
500
+ }
501
+ return new HttpRequest(request.method, request.url, request.body, {
502
+ headers,
503
+ params,
504
+ responseType: request.responseType,
505
+ withCredentials: request.withCredentials
506
+ });
507
+ };
508
+ const deserializeResponse = (res) => {
509
+ const response = JSON.parse(res);
510
+ return new HttpResponse({
511
+ url: response.url,
512
+ headers: new HttpHeaders(response.headers),
513
+ body: response.body,
514
+ status: response.status,
515
+ statusText: response.statusText,
516
+ });
517
+ };
518
+ class NgHttpCachingBrowserStorage {
519
+ constructor(storage) {
520
+ this.storage = storage;
521
+ }
522
+ get size() {
523
+ let count = 0;
524
+ for (let i = 0, e = this.storage.length; i < e; i++) {
525
+ const key = this.storage.key(i);
526
+ if (key && key.startsWith(KEY_PREFIX)) {
527
+ count++;
528
+ }
529
+ }
530
+ return count;
531
+ }
532
+ clear() {
533
+ for (let i = 0, e = this.storage.length; i < e; i++) {
534
+ const key = this.storage.key(i);
535
+ if (key && key.startsWith(KEY_PREFIX)) {
536
+ this.storage.removeItem(key);
537
+ }
538
+ }
539
+ }
540
+ delete(key) {
541
+ this.storage.removeItem(KEY_PREFIX + key);
542
+ return true;
543
+ }
544
+ forEach(callbackfn) {
545
+ // iterate this.storage
546
+ const lenPrefix = KEY_PREFIX.length;
547
+ for (let i = 0, e = this.storage.length; i < e; i++) {
548
+ const key = this.storage.key(i);
549
+ if (key && key.startsWith(KEY_PREFIX)) {
550
+ const value = this.get(key.substring(lenPrefix));
551
+ if (value) {
552
+ callbackfn(value, key);
553
+ }
554
+ }
555
+ }
556
+ }
557
+ get(key) {
558
+ const item = this.storage.getItem(KEY_PREFIX + key);
559
+ if (item) {
560
+ const parsedItem = JSON.parse(item);
561
+ return {
562
+ url: parsedItem.url,
563
+ response: deserializeResponse(parsedItem.response),
564
+ request: deserializeRequest(parsedItem.request),
565
+ addedTime: parsedItem.addedTime,
566
+ version: parsedItem.version
567
+ };
568
+ }
569
+ return undefined;
570
+ }
571
+ has(key) {
572
+ return this.storage.getItem(KEY_PREFIX + key) !== undefined;
573
+ }
574
+ set(key, value) {
575
+ this.storage.setItem(KEY_PREFIX + key, JSON.stringify({
576
+ url: value.url,
577
+ response: serializeResponse(value.response),
578
+ request: serializeRequest(value.request),
579
+ addedTime: value.addedTime
580
+ }));
581
+ }
581
582
  }
582
583
 
583
- class NgHttpCachingLocalStorage extends NgHttpCachingBrowserStorage {
584
- constructor() {
585
- super(localStorage);
586
- }
584
+ class NgHttpCachingLocalStorage extends NgHttpCachingBrowserStorage {
585
+ constructor() {
586
+ super(localStorage);
587
+ }
587
588
  }
588
589
 
589
- class NgHttpCachingSessionStorage extends NgHttpCachingBrowserStorage {
590
- constructor() {
591
- super(sessionStorage);
592
- }
590
+ class NgHttpCachingSessionStorage extends NgHttpCachingBrowserStorage {
591
+ constructor() {
592
+ super(sessionStorage);
593
+ }
593
594
  }
594
595
 
595
- /*
596
- * Public API Surface of ng-http-caching
596
+ /*
597
+ * Public API Surface of ng-http-caching
597
598
  */
598
599
 
599
- /**
600
- * Generated bundle index. Do not edit.
600
+ /**
601
+ * Generated bundle index. Do not edit.
601
602
  */
602
603
 
603
604
  export { NG_HTTP_CACHING_CONFIG, NG_HTTP_CACHING_DAY_IN_MS, NG_HTTP_CACHING_HOUR_IN_MS, NG_HTTP_CACHING_MINUTE_IN_MS, NG_HTTP_CACHING_MONTH_IN_MS, NG_HTTP_CACHING_SECOND_IN_MS, NG_HTTP_CACHING_WEEK_IN_MS, NG_HTTP_CACHING_YEAR_IN_MS, NgHttpCachingBrowserStorage, NgHttpCachingConfigDefault, NgHttpCachingHeaders, NgHttpCachingHeadersList, NgHttpCachingInterceptorService, NgHttpCachingLocalStorage, NgHttpCachingMemoryStorage, NgHttpCachingModule, NgHttpCachingService, NgHttpCachingSessionStorage, NgHttpCachingStrategy, deserializeRequest, deserializeResponse, serializeRequest, serializeResponse };