nexus site path corrected
[portal.git] / ecomp-portal-FE / client / bower_components / angular-cache / README.md
1 # angular-cache
2
3 [![bower version](https://img.shields.io/bower/v/angular-cache.svg?style=flat)](https://www.npmjs.org/package/angular-cache)
4 [![npm version](https://img.shields.io/npm/v/angular-cache.svg?style=flat)](https://www.npmjs.org/package/angular-cache)
5 [![Circle CI](https://img.shields.io/circleci/project/jmdobry/angular-cache/master.svg?style=flat)](https://circleci.com/gh/jmdobry/angular-cache/tree/master)
6 [![npm downloads](https://img.shields.io/npm/dm/angular-cache.svg?style=flat)](https://www.npmjs.org/package/angular-cache)
7 [![codecov](https://img.shields.io/codecov/c/github/jmdobry/angular-cache.svg)](https://codecov.io/gh/jmdobry/angular-cache)
8
9 A very useful replacement for Angular's $cacheFactory.
10
11 __versions of angular-cache below 4.0.0 have been deprecated, see the [breaking changes](https://github.com/jmdobry/angular-cache/blob/master/CHANGELOG.md) in 4.0.0__
12
13 ### Table of Contents
14 - [Quick Start](#quick-start)
15 - [The Basics](#the-basics)
16 - [Working with a cache](#working-with-a-cache)
17 - [Configuration Options](#configuration-options)
18 - [Using angular-cache with $http](#using-angular-cache-with-http)
19 - [Using angular-cache with localStorage](#using-angular-cache-with-localstorage)
20 - [API Reference](#api-reference)
21
22 ### Quick Start
23 `bower install --save angular-cache` or `npm install --save angular-cache`.
24
25 ```js
26 angular.module('myApp', ['angular-cache'])
27   .config(function (CacheFactoryProvider) {
28     angular.extend(CacheFactoryProvider.defaults, { maxAge: 15 * 60 * 1000 });
29   })
30   .service('BookService', function (CacheFactory, $http) {
31     if (!CacheFactory.get('bookCache')) {
32       // or CacheFactory('bookCache', { ... });
33       CacheFactory.createCache('bookCache', {
34         deleteOnExpire: 'aggressive',
35         recycleFreq: 60000
36       });
37     }
38
39     var bookCache = CacheFactory.get('bookCache');
40
41     return {
42       findBookById: function (id) {
43         return $http.get('/api/books/' + id, { cache: bookCache });
44       }
45     };
46   });
47 ```
48
49 #### Why would you want to replace $cacheFactory?
50
51 | Feature | $cacheFactory | angular-cache |
52 | ----------- | ------------------- | --------------- |
53 | core implementation usable outside of Angular | no | [__yes__](https://github.com/jmdobry/CacheFactory) |
54 | key/value store | __yes__ | __yes__ |
55 | in-memory support | __yes__ | __yes__ |
56 | localStorage support | no | __yes__ |
57 | sessionStorage support | no | __yes__ |
58 | custom storage support | no | __yes__ |
59 | can set maximum capacity | __yes__ | __yes__ |
60 | LRU support | __yes__ | __yes__ |
61 | support for time-based expiration of items | no | __yes__ |
62 | remove all expired items | n/a | __yes__ |
63 | "touch" an item | n/a | __yes__ |
64 | execute callback when an item expires | n/a | __yes__ |
65 | get info about cache | __yes__ | __yes__ |
66 | get info about single item | no | __yes__ |
67 | get item by key | __yes__ | __yes__ |
68 | remove item by key | __yes__ | __yes__ |
69 | remove all items | __yes__ | __yes__ |
70 | get keys of all caches | no | __yes__ |
71 | clear all caches | no | __yes__ |
72 | disable/enable a cache | no | __yes__ |
73 | "touch" all items in all caches | n/a | __yes__ |
74 | remove expired items from all caches | n/a | __yes__ |
75 | get all keys in a cache | no | __yes__ |
76 | clear a cache on a given interval | no | __yes__ |
77
78 ### The Basics
79
80 First, inject `CacheFactory` then create a cache. Let's go:
81
82 ```js
83 app.service('myService', function (CacheFactory) {
84   var profileCache;
85
86   // Check to make sure the cache doesn't already exist
87   if (!CacheFactory.get('profileCache')) {
88     profileCache = CacheFactory('profileCache');
89   }
90 });
91 ```
92
93 Let's add some items to the cache:
94
95 ```js
96 profileCache.put('/profiles/34', {
97     name: 'John',
98     skills: ['programming', 'piano']
99 });
100
101 profileCache.put('/profiles/22', {
102     name: 'Sally',
103     skills: ['marketing', 'climbing', 'painting']
104 });
105 ```
106
107 Right now, these items will stay in the cache until a page refresh.
108
109 Let's have items which are added to `profileCache` expire after an hour:
110
111 ```js
112 profileCache = CacheFactory('profileCache', {
113   maxAge: 60 * 60 * 1000 // 1 hour
114 });
115 ```
116
117 Perfect. Say we also want the items removed from the cache when they expire:
118
119 ```js
120 profileCache = CacheFactory('profileCache', {
121   maxAge: 60 * 60 * 1000 // 1 hour,
122   deleteOnExpire: 'aggressive'
123 });
124 ```
125
126 Let's say that when the items do expire, we want to refresh them with new values:
127
128 ```js
129 profileCache = CacheFactory('profileCache', {
130   maxAge: 60 * 60 * 1000 // 1 hour,
131   deleteOnExpire: 'aggressive',
132   onExpire: function (key, value) {
133     $http.get(key).success(function (data) {
134       profileCache.put(key, data);
135     });
136   }
137 });
138 ```
139
140 Or say we want all of our caches to use that configuration as their default:
141
142 ```js
143 angular.module('app', ['angular-cache']).config(function (CacheFactoryProvider) {
144   angular.extend(CacheFactoryProvider.defaults, {
145     maxAge: 3600000,
146     deleteOnExpire: 'aggressive',
147     onExpire: function (key, value) {
148       var _this = this; // "this" is the cache in which the item expired
149       angular.injector(['ng']).get('$http').get(key).success(function (data) {
150         _this.put(key, data);
151       });
152     }
153   });
154 });
155 ```
156
157 ### Working with a cache
158
159 We can retrieve items from a cache like so:
160
161 ```js
162 var profile = profileCache.get('/profiles/34');
163
164 profile.name; // 'John'
165 ```
166
167 And get information about items in the cache:
168
169 ```js
170 var info = profileCache.info('/profiles/34');
171
172 info.isExpired; // false
173 // etc.
174 ```
175
176 and information about the cache itself:
177
178 ```
179 var info = profileCache.info();
180
181 info.size; // 2
182 info.maxAge; // 3600000
183 info.deleteOnExpire; // 'aggressive'
184 // etc.
185 ```
186
187 Items are easily removed, and we can destroy our cache when we're done with it:
188
189 ```js
190 profileCache.remove('/profiles/34');
191
192 profileCache.get('/profiles/34'); // undefined
193
194 profileCache.destroy();
195
196 CacheFactory.get('profileCache'); // undefined
197 ```
198
199 ### Configuration Options
200
201 These options apply to:
202
203 - `CacheFactory(cacheId[, options)`
204 - `CacheFactory.createCache(cacheId[, options])`
205 - `Cache#setOptions(options[, strict])`
206 - `Cache#setMaxAge(maxAge)`, `Cache#setOnExpire(onExpire)`, etc.
207
208 ##### `cacheFlushInterval`
209
210 If set, remove all items from a cache on an interval after the given number of milliseconds. Default: `null`.
211
212 ##### `capacity`
213
214 Maximum number of items a cache can hold. Adding more items than the capacity will cause the cache to operate like an LRU cache, removing the least recently used items to stay under capacity. Default: `Number.MAX_VALUE`.
215
216 ##### `deleteOnExpire`
217
218 Determines the behavior of a cache when an item expires. Default: `none`.
219
220 Possible values:
221
222 - `none` - Cache will do nothing when an item expires.
223 - `passive` - Cache will do nothing when an item expires. Expired items will remain in the cache until requested, at which point they are removed, and `undefined` is returned.
224 - `aggressive` - Cache will remove expired items as soon as they are discovered.
225
226 ##### `disabled`
227
228 Determines whether a cache is disabled. Default: `false`.
229
230 ##### `onExpire`
231
232 A callback function to be executed whenever an expired item is removed from a cache when the cache is in `passive` or `aggressive` mode. Will be passed the `key` and `value` of the expired item.
233
234 Will be passed a third `done` argument if the cache is in `passive` mode. This allows you to synchronously access the `key` and `value` of the expired item when you make the `Cache#get(key[, options])` call that is the reason the expired item is being removed in the first place. Default: `null`.
235
236 ##### `maxAge`
237
238 The number of milliseconds until a newly inserted item expires. Default: `Number.MAX_VALUE`.
239
240 ##### `recycleFreq`
241
242 Determines how often a cache will scan for expired items when in `aggressive` mode. Default: `1000` (milliseconds).
243
244 ##### `storageImpl`
245
246 Provide a custom storage medium, e.g. a polyfill for `localStorage`. Default: `null`.
247
248 Must implement:
249
250 - `setItem` - Same API as `localStorage.setItem(key, value)`
251 - `getItem` - Same API as `localStorage.getItem(key)`
252 - `removeItem` - Same API as `localStorage.removeItem(key)`
253
254 ##### `storageMode`
255
256 Determines the storage medium used by a cache. Default: `memory`.
257
258 Possible values:
259
260 - `memory` - Cache will hold data in memory. Data is cleared when the page is refreshed.
261 - `localStorage` - Cache will hold data in `localStorage` if available. Data is _not_ cleared when the page is refreshed.
262 - `sessionStorage` - Cache will hold data in `sessionStorage` if available. Data is _not_ cleared when the page is refreshed.
263
264 ##### `storagePrefix`
265
266 Determines the namespace of a cache when `storageMode` is set to `localStorage` or `sessionStorage`. Make it a shorter string to save space. Default: `angular-cache.caches.`.
267
268 ##### `storeOnReject`
269
270 If inserting a promise into a cache, also insert the rejection value if the promise rejects. Default: `false`.
271
272 ##### storeOnResolve
273
274 If inserting a promise into a cache, also insert the resolved value if the promise resolves. Default: `false`.
275
276 ### Using angular-cache with $http
277
278 __Note:__ The downside of letting `$http` handle caching for you is that it caches the responses (in string form) to your requests–not the JavaScript Object parsed from the response body. This means you can't interact with the data in the cache used by `$http`. See below for how to handle the caching yourself, which gives you more control and the ability to interact with the cache (use it as a data store).
279
280 Configure `$http` to use a cache created by `CacheFactory` by default:
281
282 ```js
283 app.run(function ($http, CacheFactory) {
284   $http.defaults.cache = CacheFactory('defaultCache', {
285     maxAge: 15 * 60 * 1000, // Items added to this cache expire after 15 minutes
286     cacheFlushInterval: 60 * 60 * 1000, // This cache will clear itself every hour
287     deleteOnExpire: 'aggressive' // Items will be deleted from this cache when they expire
288   });
289 });
290 ```
291
292 ```js
293 app.service('MyService', function ($http, $q) {
294   return {
295     getDataById: function (id) {
296       var deferred = $q.defer();
297       var start = new Date().getTime();
298
299       $http.get('api/data/' + id, {
300         cache: true
301       }).success(function (data) {
302         console.log('time taken for request: ' + (new Date().getTime() - start) + 'ms');
303         deferred.resolve(data);
304       });
305       return deferred.promise;
306     }
307   };
308 });
309 ```
310
311 ```js
312 app.controller('myCtrl', function (MyService) {
313   MyService.getDataById(1).then(function (data) {
314     // e.g. "time taken for request: 2375ms"
315     // Data returned by this next call is already cached.
316     return MyService.getDataById(1).then(function (data) {
317       // e.g. "time taken for request: 1ms"
318     });
319   });
320 });
321 ```
322
323 Tell $http to use a cache created by CacheFactory for a specific request:
324
325 ```js
326 app.service('MyService', function ($q, $http, CacheFactory) {
327
328   CacheFactory('dataCache', {
329     maxAge: 15 * 60 * 1000, // Items added to this cache expire after 15 minutes
330     cacheFlushInterval: 60 * 60 * 1000, // This cache will clear itself every hour
331     deleteOnExpire: 'aggressive' // Items will be deleted from this cache when they expire
332   });
333
334   return {
335     getDataById: function (id) {
336       var deferred = $q.defer();
337       var start = new Date().getTime();
338
339       $http.get('api/data/' + id, {
340         cache: CacheFactory.get('dataCache')
341       }).success(function (data) {
342         console.log('time taken for request: ' + (new Date().getTime() - start) + 'ms');
343         deferred.resolve(data);
344       });
345       return deferred.promise;
346     }
347   };
348 });
349 ```
350
351 ```js
352 app.controller('myCtrl', function (MyService) {
353   MyService.getDataById(1).then(function (data) {
354     // e.g. "time taken for request: 2375ms"
355     // Data returned by this next call is already cached.
356     return MyService.getDataById(1).then(function (data) {
357       // e.g. "time taken for request: 1ms"
358     });
359   });
360 });
361 ```
362
363 Do your own caching while using the $http service:
364
365 ```js
366 app.service('MyService', function ($q, $http, CacheFactory) {
367
368   CacheFactory('dataCache', {
369     maxAge: 15 * 60 * 1000, // Items added to this cache expire after 15 minutes
370     cacheFlushInterval: 60 * 60 * 1000, // This cache will clear itself every hour
371     deleteOnExpire: 'aggressive' // Items will be deleted from this cache when they expire
372   });
373
374   return {
375     getDataById: function (id) {
376       var deferred = $q.defer();
377       var start = new Date().getTime();
378       var dataCache = CacheFactory.get('dataCache');
379
380       // Now that control of inserting/removing from the cache is in our hands,
381       // we can interact with the data in "dataCache" outside of this context,
382       // e.g. Modify the data after it has been returned from the server and
383       // save those modifications to the cache.
384       if (dataCache.get(id)) {
385         deferred.resolve(dataCache.get(id));
386       } else {
387         $http.get('api/data/' + id).success(function (data) {
388           console.log('time taken for request: ' + (new Date().getTime() - start) + 'ms');
389           dataCache.put(id, data);
390           deferred.resolve(data);
391           });
392       }
393       return deferred.promise;
394     }
395   };
396 });
397 ```
398
399 ```js
400 app.controller('myCtrl', function (MyService) {
401   MyService.getDataById(1).then(function (data) {
402     // e.g. "time taken for request: 2375ms"
403     // Data returned by this next call is already cached.
404     return MyService.getDataById(1).then(function (data) {
405       // e.g. "time taken for request: 1ms"
406     });
407   });
408 });
409 ```
410
411 ### Using angular-cache with localStorage
412
413 ```js
414 app.service('myService', function (CacheFactory) {
415
416   // This cache will sync itself with localStorage if it exists, otherwise it won't. Every time the
417   // browser loads this app, this cache will attempt to initialize itself with any data it had
418   // already saved to localStorage (or sessionStorage if you used that).
419   var myAwesomeCache = CacheFactory('myAwesomeCache', {
420     maxAge: 15 * 60 * 1000, // Items added to this cache expire after 15 minutes.
421     cacheFlushInterval: 60 * 60 * 1000, // This cache will clear itself every hour.
422     deleteOnExpire: 'aggressive', // Items will be deleted from this cache right when they expire.
423     storageMode: 'localStorage' // This cache will use `localStorage`.
424   });
425 });
426 ```
427
428 Using angular-cache in browsers that DON'T support localStorage:
429
430 Option 1 - Do nothing (the cache will just store data in memory)
431
432 Option 2 - Create/use a polyfill that provides the global `localStorage` and `sessionStorage` objects. angular-cache will attempt to use these if it finds them.
433
434 Option 3 - Tell angular-cache exactly which polyfill to use (also useful if you just want to use your own implementation/wrapper for localStorage):
435
436 ```js
437 app.service('myService', function (CacheFactory) {
438
439   var localStoragePolyfill = {
440     getItem: function (key) { ... },
441     setItem: function (key, value) { ... },
442     removeItem: function (key) { ... }
443   };
444
445   // Always use the polyfill
446   var myAwesomeCache = CacheFactory('myAwesomeCache', {
447     maxAge: 15 * 60 * 1000, // Items added to this cache expire after 15 minutes.
448     cacheFlushInterval: 60 * 60 * 1000, // This cache will clear itself every hour.
449     deleteOnExpire: 'aggressive', // Items will be deleted from this cache right when they expire.
450     storageMode: 'localStorage', // This cache will use `localStorage`.
451     storageImpl: localStoragePolyfill // angular-cache will use this polyfill instead of looking for localStorage
452   });
453
454   // Conditionally use the polyfill
455   var options = {
456     maxAge: 15 * 60 * 1000, // Items added to this cache expire after 15 minutes.
457     cacheFlushInterval: 60 * 60 * 1000, // This cache will clear itself every hour.
458     deleteOnExpire: 'aggressive', // Items will be deleted from this cache right when they expire.
459     storageMode: 'localStorage' // This cache will use `localStorage`.
460   };
461   if (!window.localStorage) {
462     options.storageImpl = localStoragePolyfill;
463   }
464   var myAwesomeCache = CacheFactory('myAwesomeCache', options);
465 });
466 ```
467
468 Documentation on the interface that must be implemented by any storageImpl polyfill used by angular-cache can be found on the W3C Recommendation page for webstorage. The interface itself looks like:
469
470 ```
471 interface Storage {
472   readonly attribute unsigned long length;
473   DOMString? key(unsigned long index);
474   getter DOMString getItem(DOMString key);
475   setter creator void setItem(DOMString key, DOMString value);
476   deleter void removeItem(DOMString key);
477   void clear();
478 };
479 ```
480
481 angular-cache cares only about these three methods:
482
483 - `setItem`
484 - `getItem`
485 - `removeItem`
486
487 One developer suggested using store.js–a wrapper and polyfill for localStorage. However, store.js has its own API that doesn't match that of the webstorage spec, so if you want to use store.js or any other 3rd-party polyfill then you'll need to create a wrapper for it if it doesn't have the same API as localStorage . For example:
488
489 ```js
490 var storeJsToStandard {
491   getItem: store.get,
492   setItem: store.set,
493   removeItem: store.remove
494 };
495
496 CacheFactory('myNewCache', {
497   storageMode: 'localStorage',
498   storageImpl: storeJsToStandard
499 });
500 ```
501
502 ### API Reference
503
504 ##### `CacheFactory(cacheId[, options])` & `CacheFactory.createCache(cacheId[, options])`
505
506 Create a cache. Cache must not already exist. `cacheId` must be a string. `options` is an optional argument and must be an object. Any options you pass here will override any default options.
507
508 ```js
509 var cache = CacheFactory('cache');
510 var cache2 = CacheFactory.createCache('cache2');
511 var cache3 = CacheFactory('cache', { maxAge: 900000 });
512 var cache4 = CacheFactory('cache'); // Error "cache already exists!"
513 ```
514
515 ##### `CacheFactory.get(cacheId)`
516
517 Return the cache with the given `cacheId`.
518
519 ##### `CacheFactory.info()`
520
521 Return an object of key-value pairs, the keys being cache ids and the values being the result of `.info()` being called on each cache.
522
523 ##### `CacheFactory.keySet()`
524
525 Return the ids of all registered caches as an object.
526
527 ##### `CacheFactory.keys()`
528
529 Return the ids of all registered caches as an array.
530
531 ##### `CacheFactory.destroy(cacheId)`
532
533 Destroy the cache with the given `cacheId`.
534
535 ##### `CacheFactory.destroyAll()`
536
537 Destroy all registered caches.
538
539 ##### `CacheFactory.clearAll()`
540
541 Remove all data from all registered caches.
542
543 ##### `CacheFactory.enableAll()`
544
545 Enable all registered caches.
546
547 ##### `CacheFactory.disableAll()`
548
549 Disable all registered caches.
550
551 ##### `CacheFactory.touchAll()`
552
553 Call `.touch()` on all registered caches.
554
555 ##### `CacheFactory.removeExpiredFromAll()`
556
557 Call `.removeExpired()` on all registered caches. Returns a hash of any expired items, keyed by cache id.
558
559 ##### `Cache#get(key[, options])`
560
561 Return the item with the given `key`. `options`, if provided, must be an object.
562
563 If the cache is in `passive` mode, then `options.onExpire` can be a function that will be called with the `key` and `value` of the requested item if the requested item is expired, with the `get` call itself returning undefined.
564
565 ##### `Cache#put(key, value[, options])`
566
567 Insert the item with the given `key` and `value` into the cache. `options`, if provided, must be an object.
568
569 If inserting a promise, `options.storeOnReject` determines whether to insert the rejection value if the promise rejects (overriding the default `storeOnReject` setting for the cache).
570 If inserting a promise, `options.storeOnResolve` determines whether to insert the resolved value if the promise resolves (overriding the default `storeOnResolve` setting for the cache).
571
572 ##### `Cache.remove(key)`
573
574 Remove and return the item with the given `key`, if it is in the cache.
575
576 ##### `Cache.removeAll()`
577
578 Remove all items in the cache.
579
580 ##### `Cache.removeExpired()`
581
582 Remove and return all expired items in the cache.
583
584 ##### `Cache.destroy()`
585
586 Completely destroy this cache and its data.
587
588 ##### `Cache#info([key])`
589
590 `Cache#info()` returns an object containing information about the cache.
591
592 `Cache#info(key)` returns an object containing information about the item with the given `key`, if the item is in the cache.
593
594 ##### `Cache#keySet()`
595
596 Return the keys of all items in the cache as an object.
597
598 ##### `Cache#keys()`
599
600 Return the keys of all items in the cache as an array.
601
602 ##### `Cache#enable()`
603
604 Enable the cache.
605
606 ##### `Cache#disable()`
607
608 Disable the cache.
609
610 ##### `Cache#values()`
611
612 Return all values in the cache.
613
614 ##### `Cache#touch([key])`
615
616 `Cache#touch()` will "touch" all items in the cache.
617 `Cache#touch(key)` will "touch" the item with the given `key`.
618
619 ##### `Cache#setCacheFlushInterval(cacheFlushInterval)`
620
621 Set the `cacheFlushInterval` for the cache.
622
623 ##### `Cache#setCapacity(capacity)`
624
625 Set the `capacity` for the cache. Setting this lower than the current item count will result in those items being removed.
626
627 ##### `Cache#setDeleteOnExpire(deleteOnExpire)`
628
629 Set the `deleteOnExpire` for the cache.
630
631 ##### `Cache#setMaxAge(maxAge)`
632
633 Set the `maxAge` for the cache.
634
635 ##### `Cache#setOnExpire(onExpire)`
636
637 Set the `onExpire` for the cache.
638
639 ##### `Cache#setRecycleFreq(recycleFreq)`
640
641 Set the `recycleFreq` for the cache.
642
643 ##### `Cache#setStorageMode(storageMode)`
644
645 Set the `storageMode` for the cache. This will move data from the current storage medium to the new one.
646
647 ##### `Cache#setOptions(options[, strict])`
648
649 Set multiple options for the cache at a time. Setting `strict` to `true` will reset options for the cache that are not specifically set in the `options` hash to `CacheFactoryProvider.defaults`.
650
651 ### License
652 [MIT License](https://github.com/jmdobry/angular-cache/blob/master/LICENSE)
653
654 Copyright (C) 2013-2016 angular-cache project authors
655
656 Permission is hereby granted, free of charge, to any person obtaining a copy of
657 this software and associated documentation files (the "Software"), to deal in
658 the Software without restriction, including without limitation the rights to
659 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
660 of the Software, and to permit persons to whom the Software is furnished to do
661 so, subject to the following conditions:
662
663 The above copyright notice and this permission notice shall be included in all
664 copies or substantial portions of the Software.
665
666 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
667 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
668 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
669 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
670 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
671 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.