• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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