1var path = require( 'path' ); 2var fs = require( 'fs' ); 3var utils = require( './utils' ); 4var del = require( './del' ); 5var writeJSON = utils.writeJSON; 6 7var cache = { 8 /** 9 * Load a cache identified by the given Id. If the element does not exists, then initialize an empty 10 * cache storage. If specified `cacheDir` will be used as the directory to persist the data to. If omitted 11 * then the cache module directory `./cache` will be used instead 12 * 13 * @method load 14 * @param docId {String} the id of the cache, would also be used as the name of the file cache 15 * @param [cacheDir] {String} directory for the cache entry 16 */ 17 load: function ( docId, cacheDir ) { 18 var me = this; 19 20 me._visited = { }; 21 me._persisted = { }; 22 me._pathToFile = cacheDir ? path.resolve( cacheDir, docId ) : path.resolve( __dirname, './.cache/', docId ); 23 24 if ( fs.existsSync( me._pathToFile ) ) { 25 me._persisted = utils.tryParse( me._pathToFile, { } ); 26 } 27 }, 28 29 /** 30 * Load the cache from the provided file 31 * @method loadFile 32 * @param {String} pathToFile the path to the file containing the info for the cache 33 */ 34 loadFile: function ( pathToFile ) { 35 var me = this; 36 var dir = path.dirname( pathToFile ); 37 var fName = path.basename( pathToFile ); 38 39 me.load( fName, dir ); 40 }, 41 42 /** 43 * Returns the entire persisted object 44 * @method all 45 * @returns {*} 46 */ 47 all: function () { 48 return this._persisted; 49 }, 50 51 keys: function () { 52 return Object.keys( this._persisted ); 53 }, 54 /** 55 * sets a key to a given value 56 * @method setKey 57 * @param key {string} the key to set 58 * @param value {object} the value of the key. Could be any object that can be serialized with JSON.stringify 59 */ 60 setKey: function ( key, value ) { 61 this._visited[ key ] = true; 62 this._persisted[ key ] = value; 63 }, 64 /** 65 * remove a given key from the cache 66 * @method removeKey 67 * @param key {String} the key to remove from the object 68 */ 69 removeKey: function ( key ) { 70 delete this._visited[ key ]; // esfmt-ignore-line 71 delete this._persisted[ key ]; // esfmt-ignore-line 72 }, 73 /** 74 * Return the value of the provided key 75 * @method getKey 76 * @param key {String} the name of the key to retrieve 77 * @returns {*} the value from the key 78 */ 79 getKey: function ( key ) { 80 this._visited[ key ] = true; 81 return this._persisted[ key ]; 82 }, 83 84 /** 85 * Remove keys that were not accessed/set since the 86 * last time the `prune` method was called. 87 * @method _prune 88 * @private 89 */ 90 _prune: function () { 91 var me = this; 92 var obj = { }; 93 94 var keys = Object.keys( me._visited ); 95 96 // no keys visited for either get or set value 97 if ( keys.length === 0 ) { 98 return; 99 } 100 101 keys.forEach( function ( key ) { 102 obj[ key ] = me._persisted[ key ]; 103 } ); 104 105 me._visited = { }; 106 me._persisted = obj; 107 }, 108 109 /** 110 * Save the state of the cache identified by the docId to disk 111 * as a JSON structure 112 * @param [noPrune=false] {Boolean} whether to remove from cache the non visited files 113 * @method save 114 */ 115 save: function ( noPrune ) { 116 var me = this; 117 118 (!noPrune) && me._prune(); 119 writeJSON( me._pathToFile, me._persisted ); 120 }, 121 122 /** 123 * remove the file where the cache is persisted 124 * @method removeCacheFile 125 * @return {Boolean} true or false if the file was successfully deleted 126 */ 127 removeCacheFile: function () { 128 return del( this._pathToFile ); 129 }, 130 /** 131 * Destroy the file cache and cache content. 132 * @method destroy 133 */ 134 destroy: function () { 135 var me = this; 136 me._visited = { }; 137 me._persisted = { }; 138 139 me.removeCacheFile(); 140 } 141}; 142 143module.exports = { 144 /** 145 * Alias for create. Should be considered depreacted. Will be removed in next releases 146 * 147 * @method load 148 * @param docId {String} the id of the cache, would also be used as the name of the file cache 149 * @param [cacheDir] {String} directory for the cache entry 150 * @returns {cache} cache instance 151 */ 152 load: function ( docId, cacheDir ) { 153 return this.create( docId, cacheDir ); 154 }, 155 156 /** 157 * Load a cache identified by the given Id. If the element does not exists, then initialize an empty 158 * cache storage. 159 * 160 * @method create 161 * @param docId {String} the id of the cache, would also be used as the name of the file cache 162 * @param [cacheDir] {String} directory for the cache entry 163 * @returns {cache} cache instance 164 */ 165 create: function ( docId, cacheDir ) { 166 var obj = Object.create( cache ); 167 obj.load( docId, cacheDir ); 168 return obj; 169 }, 170 171 createFromFile: function ( filePath ) { 172 var obj = Object.create( cache ); 173 obj.loadFile( filePath ); 174 return obj; 175 }, 176 /** 177 * Clear the cache identified by the given id. Caches stored in a different cache directory can be deleted directly 178 * 179 * @method clearCache 180 * @param docId {String} the id of the cache, would also be used as the name of the file cache 181 * @param cacheDir {String} the directory where the cache file was written 182 * @returns {Boolean} true if the cache folder was deleted. False otherwise 183 */ 184 clearCacheById: function ( docId, cacheDir ) { 185 var filePath = cacheDir ? path.resolve( cacheDir, docId ) : path.resolve( __dirname, './.cache/', docId ); 186 return del( filePath ); 187 }, 188 /** 189 * Remove all cache stored in the cache directory 190 * @method clearAll 191 * @returns {Boolean} true if the cache folder was deleted. False otherwise 192 */ 193 clearAll: function ( cacheDir ) { 194 var filePath = cacheDir ? path.resolve( cacheDir ) : path.resolve( __dirname, './.cache/' ); 195 return del( filePath ); 196 } 197}; 198