4e1062d7141ec7538cc3a60685391faf39ad1ae1b3ca37c57442de279afafd60b6ac949d58977f58cd6d3cb00982edab4ca13dcd27849e3244e44ae5953458 5.8 KB

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